Compare commits

..

360 Commits

Author SHA1 Message Date
Mario de Frutos
a2e99ac533 Merge pull request #327 from CartoDB/test_for_325
Added test for the case that arose in #325
2018-03-22 12:02:47 +01:00
Mario de Frutos
da5d3ea8d9 Added test for the case that arose in #325 2018-03-22 11:53:50 +01:00
Mario de Frutos
fed64e4850 Update NEWS.md 2018-03-21 17:20:21 +01:00
Mario de Frutos
9959581b7a Merge pull request #326 from CartoDB/325_fix_seq_error
Fixed a trucate problem with the seq rename
2018-03-21 17:14:57 +01:00
Mario de Frutos
c9f4685e5d Fix error with hyphens, moving logic to the Format part 2018-03-21 16:33:05 +01:00
Mario de Frutos
f96c334f48 Fixed a trucate problem with the seq rename. See #325 2018-03-21 12:05:56 +01:00
Mario de Frutos
04dc39bb16 Merge pull request #316 from CartoDB/quantiles-bins-updates
Updates quantile bins to use native PostgreSQL precentile functions
2018-03-19 13:09:13 +01:00
Mario de Frutos
0a6f263106 Bump version to 0.22.0 2018-03-14 12:14:50 +01:00
Andy Eschbacher
697a0a3a36 Merge branch 'master' into quantiles-bins-updates 2018-03-12 09:50:01 -04:00
Paul Ramsey
7559151ab5 Merge pull request #319 from CartoDB/seq-drop
Sequence Rename to avoid Collision. Helps interop with older ogr2ogr.
2018-03-09 10:00:59 -08:00
Paul Ramsey
2c62730301 News entry for this fix 2018-03-09 10:00:10 -08:00
Paul Ramsey
62c27ab140 Merge branch 'master' of github.com:CartoDB/cartodb-postgresql into seq-drop 2018-03-09 09:58:25 -08:00
Andy Eschbacher
17c872ed61 changes version number 2018-03-08 11:02:19 -05:00
Andy Eschbacher
6714feea8f updates news 2018-03-08 10:38:03 -05:00
Andy Eschbacher
b6b0ef704a Merge branch 'master' into quantiles-bins-updates 2018-03-08 10:33:01 -05:00
Andy Eschbacher
39998a9c88 fix syntax error oof oof 2018-03-08 10:21:43 -05:00
Andy Eschbacher
cf38d4cf25 oof include SELECT 2018-03-08 10:14:08 -05:00
Andy Eschbacher
0467c075f7 opts for array version of percentile_disc 2018-03-08 10:00:52 -05:00
Javier Goizueta
c1c55bf59f Release 0.21.0 2018-02-15 17:22:42 +01:00
Javier Goizueta
0a58c05049 Merge pull request #323 from CartoDB/321-grant-sequence
grant usage on cartodb_id sequence when sharing read write
2018-02-15 16:29:25 +01:00
Javier Goizueta
81f2fad3ad Merge pull request #322 from CartoDB/max-grid-size
Add limit to the grid-generating functions
2018-02-15 16:09:12 +01:00
Javier Goizueta
0a0f2e294b Fix tests 2018-02-15 10:27:19 +01:00
Alberto Romeu
cd4653ecc0 grant usage on cartodb_id sequence when sharing read write 2018-02-15 08:40:17 +01:00
Javier Goizueta
7ea428913a Add limit to the grid-generating functions
This adds an optinal maxcells parameter to the rectangle and hexagonal grids,
with a default value of 262144 (2^18).
An error occurs when the grids would need more cells.
2018-02-14 17:50:06 +01:00
Paul Ramsey
4050555801 Quiet errors where there's no existing sequence 2018-01-18 10:26:01 -08:00
Paul Ramsey
e4b0e7ea7a Make user final seq has the right desired name 2018-01-18 10:06:38 -08:00
Paul Ramsey
a79c2cb7a8 draft tweek on seq handling 2018-01-18 09:27:46 -08:00
Andy Eschbacher
dbaf795a79 adjust expectation to reality instead of expectation (added TODOs) 2017-12-06 08:18:24 -05:00
Andy Eschbacher
4b937de415 updates JenksTests to reflect expectations without nulls 2017-12-06 08:10:09 -05:00
Andy Eschbacher
2fe02d8154 fix alias of column 2017-12-05 16:24:11 -05:00
Andy Eschbacher
691b9a8312 moves quantile bins to use postgres precentile functions 2017-12-05 16:16:39 -05:00
Raul Marin
5243192296 Change sed in-place for tmpfiles 2017-11-14 15:57:40 +01:00
Raul Marin
8131887204 Release version 0.20.0 2017-11-13 09:35:20 +01:00
Raul Marin
36550440bf Update CONTRIBUTING with information about function labels 2017-11-13 09:35:20 +01:00
Raul Marin
9d980ab17c Mark CDB_JenksBins as VOLATILE as it uses random 2017-11-13 09:35:20 +01:00
Raul Marin
72c214a8e4 Fix regex for PARALLEL aggregations
Worked in pg10, but it didn't in pg9.5
2017-11-13 09:35:20 +01:00
Raul Marin
0f7a1c4882 Remove PARALLEL mode in older versions (up to 9.6) 2017-11-13 09:35:20 +01:00
Raul Marin
0abc2ba250 Add PARALLEL parameter to functions 2017-11-13 09:35:20 +01:00
Raul Marin
f24d15f6ca Fix issues when running under pg10 2017-10-25 14:38:06 +02:00
Raul Marin
386eccdda2 Travis: Set dist as Ubuntu Precise 2017-10-24 15:12:24 +02:00
Rafa de la Torre
5d43faecaf Release version 0.19.2 2017-06-30 15:04:35 +02:00
Rafa de la Torre
acbaf634dc Merge pull request #306 from CartoDB/305-fix-unique-identifiers
305 fix unique identifiers
2017-06-30 15:00:49 +02:00
Rafa de la Torre
c379946c95 Update dependencies of travis script #305 2017-06-30 12:52:26 +02:00
Rafa de la Torre
711c954d1a Fix evil tests #305
Basically force generation of long name identifiers that conflict
with first choice of another unique identifier.
2017-06-29 18:53:26 +02:00
Rafa de la Torre
ffb779eb74 Increase search space of ids by 100x #305 2017-06-29 17:54:42 +02:00
Rafa de la Torre
8db73ae9bd Add test for faulty use case #305 2017-06-29 17:53:43 +02:00
Mario de Frutos
208ebb2724 Update NEWS.md for version 0.19.1 2017-06-05 11:20:38 +02:00
Mario de Frutos
951ec51968 Merge pull request #302 from CartoDB/regenerate_overviews_deadlock
Regenerate overviews deadlock
2017-06-05 11:17:14 +02:00
Mario de Frutos
8a3d506a53 Add some debug logs to be used in the future 2017-06-02 15:41:18 +02:00
Mario de Frutos
c839f74c63 Fixed travis shield 2017-06-02 15:30:19 +02:00
Mario de Frutos
8389b39c00 Bump new version 2017-06-02 15:23:47 +02:00
Mario de Frutos
4908bacc4b If existing overviews we regenerate them
Instead of make a DROP/CREATE always, in case we have existing
overviews we have to make DELETE/INSERT because DDL operations require
AccessExclusiveLock which is not compatible with AccessShareLock that
is used by the queries used to gather data for the tiler.

This incompatibility above mentioned leads to have deadlocks
2017-06-02 15:23:47 +02:00
Mario de Frutos
38fa3b485c Remove unused and old _CDB_GridCluster_Reduce_Strategy function for overviews 2017-06-02 13:05:05 +02:00
Javier Goizueta
2d473cf693 New version 0.19.0 2017-04-11 11:22:20 +02:00
Javier Goizueta
4193ff3874 Merge pull request #298 from CartoDB/295-estimate-row-count
Add CDB_EstimateRowCount function
2017-04-11 11:01:31 +02:00
Javier Goizueta
68a0752849 Use PG 9.5 for travis tests; fix tests 2017-04-10 15:58:49 +02:00
Javier Goizueta
815b5b429d Fix tests 2017-04-10 13:50:37 +02:00
Javier Goizueta
76bdb3657a Fix tests 2017-04-10 12:17:47 +02:00
Javier Goizueta
234373df11 Replace unnecessary count 2017-04-10 08:08:59 +02:00
Javier Goizueta
a486eed2e3 Add CDB_EstimateRowCount function
See #295
2017-04-07 15:35:48 +02:00
Mario de Frutos
795d92da8d Added CLA paragraph 2017-01-25 10:54:12 +01:00
Javier Goizueta
58e2e7e238 Release 0.18.5 2016-11-30 17:17:45 +01:00
Javier Goizueta
25d27263cb Merge pull request #249 from CartoDB/nullbins
Test behavior of binning fuctions with nulls
2016-11-30 16:09:23 +01:00
Javier Goizueta
bbadcc838e Merge pull request #244 from CartoDB/equalbins
Convert CDB_EqualIntervalBins to a single SQL statement and add float version
2016-11-30 16:09:05 +01:00
Javier Goizueta
b1a0904c07 Merge pull request #181 from CartoDB/update_to_cdb_stats
Fix for division by zero error on empty or homogenous array
2016-11-30 16:08:40 +01:00
Javier Goizueta
399b680b41 Merge pull request #283 from CartoDB/157-test-fixes
Fix tests: race condition with publicuser #157
2016-11-30 16:08:21 +01:00
Javier Goizueta
7c0636c5f9 Merge pull request #290 from CartoDB/286-overview-strategies
Add point overview strategies
2016-11-30 11:46:29 +01:00
Javier Goizueta
f58f870457 Remove use of first aggregator in sample-cluster overviews strategy
This is not more efficient but the geometry now corresponds to the cartodb_id
and the dependency with custom aggregators (firt) is removed.
2016-11-29 14:08:08 +01:00
Javier Goizueta
a7c8dc04e3 Release 0.18.4
This just fixes the lack of migration path from 0.18.2
2016-11-04 16:25:03 +01:00
Javier Goizueta
90ee56eb35 Merge pull request #288 from CartoDB/fix-migration
Fix migration script generation
2016-11-04 16:22:56 +01:00
Javier Goizueta
1032737600 Fix migration script generation
In the 0.18.3 release the script to migrate from 0.18.2 was missing.
This will generate a new version 0.18.4 that when install will generate
scripts to migrate from all old versions to it, so it will be possible
to migrate existing users to 0.18.4 (but not to 0.18.3)
2016-11-04 16:19:06 +01:00
Javier Goizueta
24639713f1 Release 0.18.3
The exclusion of analysis cache tables size from the quota (#281)
was meant to be included in 0.18.0 but missed the release, so
it's being released in this version.
2016-11-03 16:13:57 +01:00
Javier Goizueta
fff7e926c9 Merge pull request #287 from CartoDB/fix-281-merge
Fix 281 merge
2016-11-03 16:09:02 +01:00
Javier Goizueta
7d7ecc06f5 Merge branch 'master' into fix-281-merge 2016-11-03 15:57:24 +01:00
Javier Goizueta
5992304b47 Add a couple of overview clustering strategies 2016-11-03 13:31:04 +01:00
Alejandro Martínez
5c52e7564f Release 0.18.2 2016-10-20 16:00:12 +02:00
Alejandro Martínez
0b7fbdc1cb Merge pull request #285 from CartoDB/reorder_analysis_catalog_columns
Move "username" column to the last position on analysis_catalog - fixes #276
2016-10-20 15:44:05 +02:00
Alejandro Martínez
0bfdeae147 Move "username" column to the last position on analysis_catalog - fixes #276
Due to the way it was first implemented, the "username" column would be
on a different position depending on if it was an extension upgrade or
a fresh install.

This caused problems with pg_dumping databases and restoring them.
pg_dump does not include the extension source (so this table's schema is
not included on the dump) but does include this contents, using a COPY
without column names by default and failing due to the order difference.

After this has run, all tables (whether updated or not) will have the
"username" column on the last position.
2016-10-20 14:30:02 +02:00
Rafa de la Torre
89b2999a80 Release 0.18.1 2016-10-19 13:00:56 +02:00
Rafa de la Torre
2080d6d422 Merge pull request #284 from CartoDB/analysis-quota-factor
Analysis quota factor
2016-10-19 12:57:57 +02:00
Rafa de la Torre
bc5e23b143 Replace qmax by nominal_quota
Since the analysis quota factor can be greater than 1, `qmax` can be a
misleading name. Thus the change in var name.
2016-10-19 12:41:19 +02:00
Rafa de la Torre
64fae71a37 Default factor for analysis size from 0.2 to 2
Change the default value for the factor of analysis tables size from 0.2
to 2. I also checked it is applied on the "nominal" user quota.
2016-10-19 12:36:57 +02:00
Rafa de la Torre
594543916d New version 0.18.0 2016-10-17 18:03:00 +02:00
Rafa de la Torre
aa9286eaba Merge pull request #281 from CartoDB/277-exclude-analysis-quota
Exclude analysis cache tables from the quota
2016-10-17 17:56:21 +02:00
Rafa de la Torre
ce762f41ac Merge pull request #280 from CartoDB/279-check-analysis
Implement CDB_CheckAnalysisQuota
2016-10-17 17:55:45 +02:00
Rafa de la Torre
529b12af20 Cosmetic fix: s/INT8/bigint #279 2016-10-17 17:16:04 +02:00
Rafa de la Torre
f98b6fb0a1 Merge pull request #270 from CartoDB/269-overviews-non-null
Exclude null geometries to create overviews
2016-10-17 17:07:17 +02:00
Rafa de la Torre
30cd4cf1f9 Fix tests: race condition with publicuser #157 2016-10-17 16:31:10 +02:00
Javier Goizueta
1356131ec1 Fix tests 2016-10-14 11:22:06 +02:00
Javier Goizueta
9731ce38ec Exclude configuration tables from the quota
cdb_tablemetadata was already being excluded, but not cdb_conf and cdb_analysis_catalog
2016-10-14 10:58:16 +02:00
Javier Goizueta
07892271e5 Exclude analysis cache tables from the quota
See #277
2016-10-14 10:56:14 +02:00
Javier Goizueta
066c574709 Fix: cdb_conf table is not accessible to regular users 2016-10-11 17:52:11 +02:00
Javier Goizueta
4786e0a2ae Test cleanup 2016-10-11 17:49:50 +02:00
Javier Goizueta
358c89b332 Add tests for CDB_CheckAnalysisQuota() 2016-10-11 16:35:08 +02:00
Javier Goizueta
fa6f9a8a66 Implement CDB_CheckAnalysisQuota
see #279
2016-10-11 15:14:44 +02:00
Rafa de la Torre
091aea088e Merge pull request #275 from GeographicaGS/cdb-usertables-doc
Improve CDB_UserTables doc
2016-09-13 16:47:46 +02:00
Alberto Asuero
7ecdca1b8c Improve CDB_UserTables doc 2016-09-05 11:52:39 +02:00
Antonio Zamorano
9ee3125913 Relase 0.17.1 2016-08-16 11:30:06 +02:00
Antonio Zamorano
279eba95b7 Merge pull request #274 from CartoDB/273-cache_table_cdb_analysis_catalog
Adding a new column to have the name of the cached analysis in case there is one
2016-08-16 11:27:52 +02:00
Antonio Zamorano
b462e969a1 Adding cache_tables to the create table too 2016-08-12 11:52:24 +02:00
Antonio Zamorano
5d323456ee Chaging the type of the cached tables to a regclass array, fixes #273 2016-08-12 09:42:50 +02:00
Antonio Zamorano
6e130c336e Adding a new column to have the name of the cached analysis in case there is one, fixes #273 2016-08-11 16:27:18 +02:00
Javier Goizueta
457b614d96 Exclude null geometries to create overviews
Fixes #269
2016-07-05 16:45:12 +02:00
Raul Ochoa
415d96082e Release 0.17.0 2016-07-04 13:25:09 +02:00
Raul Ochoa
5eddf5ce8e Merge pull request #268 from CartoDB/cdb_analysis_catalog-export-config
Add export config for cdb_analysis_catalog table
2016-07-01 14:58:34 +02:00
Raul Ochoa
006c3cc50f Merge pull request #267 from CartoDB/cdb_analysis_catalog-new-fields
Add some extra fields to cdb_analysis_catalog table
2016-07-01 13:07:42 +02:00
Raul Ochoa
2b24390a8a Do not raise anything on existing columns 2016-07-01 12:56:44 +02:00
Raul Ochoa
69f04bb8b0 Add export config for cdb_analysis_catalog table
Closes #251
2016-07-01 12:36:07 +02:00
Raul Ochoa
c96bf7c7d5 Do not use plpgsql language 2016-07-01 12:34:40 +02:00
Raul Ochoa
15a8876d06 Rename to last_* pattern 2016-07-01 12:25:05 +02:00
Raul Ochoa
89e991aae9 Document new fields 2016-07-01 12:24:44 +02:00
Raul Ochoa
064b26ccd3 Add some extra fields to cdb_analysis_catalog table
Track user, error_message for failures, and last entity modifying the node.
2016-07-01 12:13:31 +02:00
Javier Goizueta
5bf35bddc1 Merge pull request #262 from CartoDB/261-overviews-quota
Exclude overviews from user data size
2016-06-20 11:03:56 +02:00
Javier Goizueta
2b69823949 💄 indent/parenthesize for clarity 2016-06-13 10:39:05 +02:00
Javier Goizueta
1f01ecae30 Exclude overviews from user data size
Fixes #261

Some internal functions from the Overviews module
have been moved to a separate file because they're now
used from Quaota function.
2016-06-13 10:04:13 +02:00
Javier Goizueta
58fd5d4060 Release 0.16.4 2016-05-30 10:45:12 +02:00
Javier Goizueta
a2a1ff6ae8 Merge pull request #258 from CartoDB/257-max-overviews-level
Fix problems computing feature density for overviews creation
2016-05-27 16:15:59 +02:00
Javier Goizueta
326aae4edb Merge pull request #259 from CartoDB/zoom_from_scale
Use standard formula for CDB_ZoomFromScale
2016-05-27 16:15:42 +02:00
Javier Goizueta
2a30eb2fd3 Fix zoom from scale condition for NULL result
And rewrite in cleaner form.
2016-05-27 15:10:20 +02:00
Javier Goizueta
0b3ad5e569 Limit the maximum zoom level
Avoid returning zoom levels greater than the maximum
'safe' level. For a zero denominator (which would imply
and infinite zoom level) return the maximum level too.
2016-05-27 12:29:52 +02:00
Paul Norman
aa302c237d Use standard formula for CDB_ZoomFromScale
postgis-vt-util comes with a standard formula for zoom from
scaleDenominator, and this is well tested. This also fixes the
function throwing an error on NULL input.
2016-05-27 12:29:43 +02:00
Javier Goizueta
9526f0448f Fix bug in feature density recursive query
If the table had x and/or y columns they were picked by an inner
select instead of the recursive arguments.
Fixes #256
2016-05-26 18:25:11 +02:00
Javier Goizueta
3399f2b9a5 Fix max overviews level usage
Note that _CDB_Feature_Density_Ref_Z_Strategy returns the first
level for which overviews should not be used, and that in some
cases _CDB_Feature_Density should look beyond the max level to
compute a feature density estimate.
2016-05-25 14:00:55 +02:00
Javier Goizueta
803b3671d0 Fixes for feature density computation
* The initial iteration of the recursive feature density query shouldn't
  start beyond the maximum level
* Correct off-by-one limit the rest of iterations
2016-05-25 11:21:12 +02:00
Javier Goizueta
c3fada29a8 Comment how the max overview level is defined 2016-05-25 11:07:06 +02:00
Javier Goizueta
86e5f6d317 Limit the maximum overview level to 23
Fixes #257

23 = 32 bits per integer - 1 sign bit - 8 bits px/tile
2016-05-24 18:18:58 +02:00
Javier Goizueta
f5f59be5b0 Release version 0.16.3
Fixes overviews creation problem
2016-05-09 13:08:50 +02:00
Javier Goizueta
d99dc394c2 Merge pull request #253 from CartoDB/252-estimateextent-quoting
Do not quote arguments to ST_EstimatedExtent
2016-05-09 13:04:44 +02:00
Javier Goizueta
8d7860dc7a Fixes #252 2016-05-09 11:54:56 +02:00
Javier Goizueta
b5427c65c8 Drop aggregate to be defined
Otherwise future versions will fail to recreate the aggregate
2016-04-29 08:46:01 +02:00
Paul Norman
3122a0479d Test behavior of binning fuctions with nulls
All test results are based off of existing behavior, which doesn't
always make sense (ref #247)
2016-04-28 09:59:33 -07:00
Paul Norman
956e56cd37 Use anyarray for equalintervalbins 2016-04-27 16:10:01 -07:00
Javier Goizueta
8f1435c049 Release 0.16.2 2016-04-27 18:30:26 +02:00
Javier Goizueta
8302f89413 Merge pull request #246 from CartoDB/245-categories-mode
Use the mode to aggregate category columns in overviews
2016-04-27 18:16:05 +02:00
Javier Goizueta
e9050178a8 Merge branch 'master' of github.com:CartoDB/cartodb-postgresql 2016-04-27 16:23:46 +02:00
Javier Goizueta
3e34ca4654 Overviews documentation fixes 2016-04-27 16:23:25 +02:00
Javier Goizueta
a067cc7da1 Generate stats used to identify category columns in overviews if needed
This only generates the stats if no stats are available for a table.
This doesn't warrant that the stats are up to date or accurate.
2016-04-27 15:06:09 +02:00
Javier Goizueta
2c43943df6 Fix syntax 2016-04-26 18:27:52 +02:00
Javier Goizueta
417cbe7902 Fix category columns aggregation in overviews
Overviews are created in cascade, each one from the inmediate
lower level, but the stats to decide if a column is a category
should be taken always from the base table.
2016-04-26 18:02:25 +02:00
Javier Goizueta
9a73703954 Use mode to aggregate categorical columns in overviews
Fixes #245
2016-04-26 15:15:24 +02:00
Rafa de la Torre
36ac831bd1 Update cartodbfy-requirements.rst
Fix broken link to doc
2016-04-26 14:43:24 +02:00
Paul Norman
b19a5fc3dc Convert CDB_EqualIntervalBins to a single SQL statement and add float version 2016-04-25 14:35:26 -07:00
Javier Goizueta
1358964628 Release 0.16.1 2016-04-25 18:47:42 +02:00
Javier Goizueta
efe381ad94 Merge pull request #243 from CartoDB/241-webmercator
Compute webmercator resolution with full accuracy
2016-04-25 17:30:40 +02:00
Javier Goizueta
f7cce21eb7 Merge pull request #242 from CartoDB/240-overviews-pixels
Adjust overview points to pixel centers
2016-04-25 17:30:25 +02:00
Javier Goizueta
18267477da Merge pull request #238 from CartoDB/235-column-names
Optimize column information functions
2016-04-25 17:30:07 +02:00
Javier Goizueta
11ad45306f Remove unneeded pg_catalog schema name 2016-04-25 16:30:58 +02:00
Javier Goizueta
75c7ae98e4 Compute webmercator resolution with full accuracy
Fixes #241
2016-04-25 14:02:26 +02:00
Javier Goizueta
3c12cf629f Optimize overview pixel adjustment for integer-pixel cells 2016-04-25 13:53:59 +02:00
Javier Goizueta
7b2100b51e Adjust overview coordinates to pixel centers
This makes the adjustment for all grid sizes, not only
for integral number of pixels.
2016-04-25 13:33:43 +02:00
Javier Goizueta
580ec38ab8 Adjust overview clustered point to pixel centers
Fixes #240
2016-04-23 15:07:06 +02:00
Raul Ochoa
897689dd43 Release 0.16.0 2016-04-19 15:44:37 +02:00
Raul Ochoa
808fc9fc25 Merge pull request #237 from CartoDB/analysis-catalog
Adds table for storing camshaft analysis nodes
2016-04-19 15:32:46 +02:00
Javier Goizueta
65415bb335 Optimize funcion CDB_COlumnType 2016-04-18 19:07:33 +02:00
Javier Goizueta
06ebb27160 Optimize internal funcion _cdb_unlimited_text_column 2016-04-18 18:50:37 +02:00
Javier Goizueta
bd5ae84e90 Optimize CDB_ColumnNames
This implementation is about 1000 times faster
2016-04-18 18:49:58 +02:00
Raul Ochoa
de5a702510 Adds table for storing camshaft analysis nodes 2016-04-18 17:41:39 +02:00
Javier Goizueta
6908fb4672 Release 0.15.1
Overviews bugfixes & enhancements
2016-04-15 18:15:35 +02:00
Javier Goizueta
a528a250d4 Merge pull request #234 from CartoDB/231-overviews-text-aggr
Aggregate small number of text items in overviews
2016-04-15 18:04:07 +02:00
Javier Goizueta
ef43623f77 Remove unneeded variable 2016-04-15 17:58:03 +02:00
Javier Goizueta
09ad550de3 Fix tests 2016-04-15 17:50:47 +02:00
Javier Goizueta
1b0f77aa96 Always retain single-valued aggregated texts
This makes columns which have the same value in a group to be aggregated
maintain that value (rather than replacing it by the multiple-value
indicator *) whatever the group value is. (Previously this happend
only for small groups)
2016-04-15 17:49:00 +02:00
Javier Goizueta
45f063d469 Aggregate small number of text items in overviews
Instead of nulling text fields for non-singleton aggregated records
concatenate distinct text values when they're few (5 or less).
Fixes #231
2016-04-15 12:37:16 +02:00
Carla
20989e2f28 Merge pull request #233 from CartoDB/232-overviews-avg
Fix AVG computation in overview tables
2016-04-15 11:10:26 +02:00
Javier Goizueta
176d69d09e Fix AVG computation in overview tables
Fixes #232
Averages of averages are not equal to overall averages.
2016-04-15 10:48:08 +02:00
Javier Goizueta
9fdbfda60a Merge pull request #228 from CartoDB/225-no-centroid-master
Use cell centers, not cluster centroids when grouping points
2016-04-15 10:06:44 +02:00
Javier Goizueta
9a3d93976c Merge pull request #227 from CartoDB/226-add_count_aggregated_features
Include and aggregate _vovw_count column to count aggregated features
2016-04-15 10:06:05 +02:00
Javier Goizueta
46b45f6dd4 Merge pull request #224 from CartoDB/223-fix-dropoverviews
Fix CDB_DropOverviews and CDB_Overviews problems
2016-04-15 10:05:28 +02:00
Carla Iriberri
fd14750ce5 Rename _vovw_count to _feature_count 2016-04-14 18:23:09 +02:00
Javier Goizueta
c595e45c11 Add _vovw_count columnt to tables for which overviews are created
Initially we planned to add this column to the queries sent to the
tiler only, but that makes the column hard to access from the editor.
2016-04-14 17:32:18 +02:00
Carla
1cf7074fb1 Merge pull request #230 from CartoDB/229-set_tolerance_px_to_1_overviews
Set tolerance to 1 pixel in overviews by default
2016-04-14 17:26:37 +02:00
Javier Goizueta
f785e71d3b Fix: numeric is a valid numeric column type
Actually this is the type of aggregated _vovw_count columns
2016-04-14 15:46:03 +02:00
Carla
14b8cd7d99 Set default value to 1 and remove typo line 2016-04-14 12:12:17 +02:00
Carla
213adcca16 Fixes tests for tolerance_px = 1.0, with no zoom 3 2016-04-14 11:24:10 +02:00
Carla
1a571c8a9c Set tolerance to 1 pixel 2016-04-14 11:13:59 +02:00
Carla Iriberri
8f44f5347a Fix indent for code clarity 2016-04-13 17:51:30 +02:00
Carla Iriberri
f96163265b Fix bug for tables without geom or with no potential overviews
If the table doesn't have geometries but the createoverviews function is
called, the current geometry type checks won't work because "null" will
not give a boolean value in the type comparisons.

Also, if the createoverviews function is called over a simple table with
would not require overviews according to the strategies it is handled
correctly.
2016-04-13 17:49:38 +02:00
Javier Goizueta
1c67214b09 Use cell centers, not cluster centroids when grouping points
Fixes #225
2016-04-13 11:14:09 +02:00
Carla Iriberri
16d08ef52b Include and aggregate _vovw_count column to count aggregated features 2016-04-12 11:10:55 +02:00
Javier Goizueta
15ac9a2cd9 Remove unneeded code 2016-04-07 10:30:10 +02:00
Javier Goizueta
ee61d46100 💄 rename variable for clarity 2016-04-07 10:24:02 +02:00
Javier Goizueta
49e7094c8a Make CDB_CreateOverview usable by superuser
CDB_CreateOverview had to be executed with the user role
corresponding to the owner of the table; now it can be executed
by the postgres user.
2016-04-07 07:52:58 +02:00
Javier Goizueta
fb910be12f Fix conversion of regclass to indentifier 2016-04-07 07:07:20 +02:00
Javier Goizueta
34c39662ec Replace use of CDB_UserTables in CDB_Overviews
Use a function that returns reclasses and schema names properly instead.
2016-04-07 00:07:45 +02:00
Javier Goizueta
84cac16d1c Temporary fix 2016-04-06 22:05:00 +02:00
Javier Goizueta
c1fc07d2ac Fix typo
This function isn't beint actively used; should consider removing it
or testing it properly
2016-04-06 18:58:37 +02:00
Javier Goizueta
5c3c0f5fc9 Fix bug in CDB_DropOverviews
Fixes #223
2016-04-06 18:57:52 +02:00
Javier Goizueta
e68d5eca45 Release 0.15.0
This release includes some overviews enhancements
2016-04-05 14:22:46 +02:00
Javier Goizueta
16a58c479d Merge pull request #221 from CartoDB/219-overviews-tolerance
New function CDB_CreateOverviewsWithToleranceInPixels
2016-04-05 14:01:25 +02:00
Javier Goizueta
06bb669d4c Add comment
Clarify the reason why some functions are dropped at the
end of the file and not where their new definitions are.
2016-04-05 13:22:07 +02:00
Javier Goizueta
00a3d6e650 Fix upgrades from prior versions 2016-04-05 13:10:00 +02:00
Javier Goizueta
f0ff197c56 Merge branch 'master' into 219-overviews-tolerance
# Conflicts:
#	scripts-available/CDB_Overviews.sql
#	test/CDB_OverviewsTest_expect
2016-04-05 13:08:22 +02:00
Javier Goizueta
c6885c2972 Merge pull request #220 from CartoDB/218-org-users-overviews
Add support for explicit schema names in overview functions
2016-04-05 13:01:16 +02:00
Javier Goizueta
57c32332e2 New function CDB_CreateOverviewsWithToleranceInPixels
This function allows defining the previously fixed parameter grid_px.
The lim parameter used to define the reference Z level is also
correlated to this value.

Fixes #219
2016-04-04 19:21:10 +02:00
Javier Goizueta
3c71eecbae Fix cases that require explicit schema name
This allows using overview functions in situations where
the base tables require being qualified with the schema name.
2016-04-04 17:45:20 +02:00
Javier Goizueta
6d9424746c Fix expected tests output 2016-04-04 17:42:10 +02:00
Javier Goizueta
c0262a05eb Fix CDB_Overviews for cases that require explicit schema name
Fixes #218
2016-04-04 17:02:59 +02:00
Javier Goizueta
aff7ae3e2e Release 0.14.4 2016-03-29 13:09:09 +02:00
Carla
01757a1b6d Merge pull request #207 from CartoDB/update_docs_user_table
Update CartoDB User table docs and minor edits on cartodbfy reqs
2016-03-29 12:58:20 +02:00
Carla
f946bfe4fe remove bigint mention 2016-03-29 12:57:58 +02:00
Javier Goizueta
a098713bfa Merge pull request #215 from CartoDB/213-makefile-echo
Fix backslashes in generated files
2016-03-29 12:51:02 +02:00
Javier Goizueta
217ff4ffb9 Merge pull request #214 from CartoDB/211-boolean-col-overviews
Support boolean columns when creating overviews
2016-03-29 12:50:57 +02:00
Javier Goizueta
a0bb7b1b03 Fix backslashes in generated files
Fixes #213
Some systems treat escaping of text passed to the echo command
from a Makefile differently.
This seems to work for our needs.
2016-03-21 14:59:05 +01:00
Javier Goizueta
4074173c05 Add support for boolean columns in overview creation 2016-03-21 12:58:29 +01:00
Javier Goizueta
603b1ceed8 Adjust Overviews test expectations 2016-03-21 12:58:00 +01:00
Javier Goizueta
0caf6c50dd Fix the tests for boolean columns and overview creation 2016-03-21 12:27:00 +01:00
Carla
224b2ce395 Update travis button to show only master status 2016-03-19 12:33:17 +01:00
Javier Goizueta
70eeab5748 Tests for revealing issue #211
Test creating overviews for tables with boolean columns
2016-03-17 19:27:51 +01:00
Carla
06c05a1d67 Merge pull request #212 from CartoDB/release_0_14_3
Release 0.14.3
2016-03-17 10:53:59 +01:00
Carla
6567d5441b Release 0.14.3 2016-03-17 10:45:54 +01:00
Carla
e10d7c3a27 Update NEWS.md 2016-03-17 10:44:12 +01:00
Carla
b89a752548 Merge pull request #210 from CartoDB/209-remove_bigint_casting_cartodb_id
Remove casting to bigint in cartodb_id column
2016-03-17 10:31:06 +01:00
Carla
90fa45b59d Remove casting to bigint 2016-03-16 11:03:46 +01:00
Carla
eb48e26eec Update CartoDB-user-table.rst 2016-03-15 16:39:56 +01:00
Carla
85e1b92199 Add non-zero requirement 2016-03-15 16:39:39 +01:00
Carla
2dc6ec618f Merge pull request #208 from CartoDB/release_0_14_2
Release 0.14.2
2016-03-15 11:19:42 +01:00
Carla
3127b9d398 Release 0.14.2 2016-03-15 10:57:06 +01:00
Carla
91158fafb0 Release 0.14.2 2016-03-15 10:52:52 +01:00
Carla
16cf70bb4a Merge pull request #202 from CartoDB/cartodbfication_cartodb_id_text
Add support to detect string cartodb_id columns
2016-03-15 10:49:22 +01:00
Carla
6ea0013343 Update cartodbfy-requirements.rst 2016-03-09 15:49:18 +01:00
Carla
80bd7f8f10 Update cartodbfy-requirements.rst 2016-03-09 15:48:33 +01:00
Carla
bb061981ad style edits 2016-03-09 15:47:26 +01:00
Carla
e289b4725f Update information and convert to .rst 2016-03-09 15:26:45 +01:00
Carla
0b8bada553 Remove unused variable 2016-03-09 11:54:59 +01:00
Carla Iriberri
7b48c2765e Fix error detection and fix tests 2016-03-08 14:06:58 +01:00
Carla Iriberri
3d0f580fc2 Add idempotence test 2016-03-08 12:10:46 +01:00
Carla Iriberri
d495bd45ba Merge branch 'cartodbfication_cartodb_id_text' of https://github.com/CartoDB/cartodb-postgresql into cartodbfication_cartodb_id_text 2016-03-08 11:59:00 +01:00
Carla Iriberri
f4b51807a1 Make cartodb_id inconsistencies fail and update tests 2016-03-08 11:58:30 +01:00
Alejandro Martínez
33b4f3718b Release 0.14.1 2016-03-07 12:05:22 +01:00
Alejandro Martínez
2e186c8565 Merge pull request #204 from CartoDB/fully-qualified-invalidations
Fully qualify invalidation calls (Fixes #198)
2016-03-07 11:45:01 +01:00
Carla
5bc725c8ab Add drop function if exists 2016-03-03 16:58:31 +01:00
Carla Iriberri
73906b60da Verbosity terse for tests 2016-03-02 18:19:21 +01:00
Carla Iriberri
03ff0365fd Change exception message and edit tests 2016-03-02 17:41:02 +01:00
Carla Iriberri
76a2cb9132 Improve exception error message 2016-03-02 17:36:45 +01:00
Alejandro Martínez
90c16fdb13 Fully qualify invalidations 2016-03-02 16:22:22 +01:00
Carla Iriberri
a80664e72a Delete outdated comments 2016-03-02 15:53:20 +01:00
Carla Iriberri
7e2193d3db Fix test expectation 2016-03-02 15:52:57 +01:00
Carla Iriberri
a18cbeb2cd Third iteration, expect a viable cartodb_id 2016-03-02 14:58:53 +01:00
Carla Iriberri
0d5f83b3c4 Rewriting function 2016-03-01 19:17:45 +01:00
Carla Iriberri
7559257d49 cartodb_id string tests 2016-03-01 17:45:15 +01:00
Carla Iriberri
1198454046 Better exception handling 2016-03-01 17:43:21 +01:00
Carla Iriberri
32307ceef0 Add support to detect string cartodb_id columns 2016-03-01 15:24:40 +01:00
Rafa de la Torre
54973c01f2 Add new version 0.14.0 with FDW support 2016-02-12 16:37:59 +01:00
Rafa de la Torre
eb4564ecee Merge pull request #199 from CartoDB/fdw-function-calls-with-schema
Fdw function calls with schema
2016-02-12 16:31:58 +01:00
Rafa de la Torre
abdc39f122 Merge pull request #200 from CartoDB/fdw-cdb_tablemetadata_text
Add CDB_TableMetadata_Text view as a proxy to access FDW tablemetadata
2016-02-12 14:47:05 +01:00
Rafa de la Torre
d2450ff361 Fix small typo in makefile 2016-02-12 11:34:04 +01:00
Rafa de la Torre
a0fe55bd5d Add a small bit of func doc about the quoting 2016-02-12 11:27:28 +01:00
Alejandro Martínez
56fed12392 Add CDB_TableMetadata_Text view as a proxy to access FDW tablemetadata 2016-02-11 19:16:00 +01:00
Rafa de la Torre
2f26b44142 tDo not quote dbname identifier
Turns out that for caching it is our standard not to have the dbname
quoted.
2016-02-11 16:10:27 +01:00
Rafa de la Torre
9596e8d9bc A couple checks for quoted idents in CDB_Last_Updated_Time 2016-02-10 19:10:57 +01:00
Rafa de la Torre
06036e2fe8 Quote identifiers returned by CDB_QueryTables_Updated_At 2016-02-10 18:58:01 +01:00
Rafa de la Torre
e870cf96e0 Merge pull request #196 from CartoDB/fdw-query-tables-updated-at
Fdw query tables updated at
2016-02-10 09:30:47 +01:00
Rafa de la Torre
2bce771488 Add some tests
Tests for:
* CDB_QueryTables_Updated_At
* CDB_Last_Updated_Time
2016-02-09 19:24:08 +01:00
Rafa de la Torre
cd4ad29e39 Remove schema when selecting from CDB_TableMetadata
to ease testing. When creating CDB_TableMetadata it is always put in
cartodb when done from the extension, but for tests it is done in
public.
2016-02-09 18:49:20 +01:00
Rafa de la Torre
d59b826d37 Fix silly bug: ordering of functions 2016-02-09 17:11:16 +01:00
Rafa de la Torre
1c637f8689 Small fixes: qualify cartodb function calls 2016-02-09 16:38:11 +01:00
Rafa de la Torre
ecbdb4a430 Move fdw-aware functions to CDB_ForeignTable.sql 2016-02-09 13:40:18 +01:00
Rafa de la Torre
eb84dd04c9 Add func CDB_Last_Updated_Time 2016-02-09 13:30:00 +01:00
Rafa de la Torre
276b5cf9ea Rename func to CDB_QueryTables_Updated_At
s/CDB_QueryTablesUpdatedAt/CDB_QueryTables_Updated_At and also add a bit
more inline doc.
2016-02-09 13:29:10 +01:00
Rafa de la Torre
ec34b8ee28 Minor changes: use plain SQL func 2016-02-08 19:29:14 +01:00
Rafa de la Torre
0f21db51b6 Simplify the code and get the updated_at 2016-02-08 19:29:14 +01:00
Rafa de la Torre
a074f4df5d Adapt CDB_QueryTablesUpdatedAt to _cdb_fqtn_from_text 2016-02-08 19:29:14 +01:00
Rafa de la Torre
1a12fd3b69 Make _cdb_fqtn_from_text return a table
with type instead of a record
2016-02-08 19:29:14 +01:00
Rafa de la Torre
78a75cf22d Implementation of _cdb_fqtn_from_text (WIP) 2016-02-08 19:29:14 +01:00
Rafa de la Torre
1e3c7ace99 Implementation of _cdb_dbname_of_foreign_table (WIP) 2016-02-08 19:29:14 +01:00
Rafa de la Torre
c210008184 Skeleton of a possible solution (WIP) 2016-02-08 19:29:14 +01:00
Rafa de la Torre
0c43fe2731 Define API of CDB_QueryTablesUpdatedAt 2016-02-08 19:29:14 +01:00
Alejandro Martínez
fdbad0f93c Fix specs on 9.3 2016-02-08 17:33:41 +01:00
Alejandro Martínez
131aee1503 Fully qualify function names 2016-02-08 16:35:26 +01:00
Alejandro Martínez
e858ddfa0b Add CDB_ForeignTable specs 2016-02-08 15:46:25 +01:00
Alejandro Martínez
edf79d9368 Add remote cdb_tablemetadata manually from public schema 2016-02-08 15:45:58 +01:00
Rafa de la Torre
c26ab0fdd1 Merge pull request #195 from CartoDB/fdw-rtorre
Fix small typos: s/name/fdw_name/
2016-02-05 13:18:24 +01:00
Rafa de la Torre
8dedd2b3f4 Fix small typos: s/name/fdw_name/ 2016-02-05 13:15:20 +01:00
Rafa de la Torre
11834dfdab Fix typo: missing semicolon 2016-02-05 10:44:55 +01:00
Alejandro Martínez
b957635e78 Add CDB_Get_Foreign_Updated_At function 2016-02-04 18:26:43 +01:00
Alejandro Martínez
a9b9f1ff6c Rename CDB_FDW_Create to CDB_FDW_Setup, formatting fixes 2016-02-04 12:06:22 +01:00
Alejandro Martínez
d7b560324a Add _Create_FDW function to create a FDW defined on the config by name 2016-02-03 18:07:23 +01:00
Alejandro Martínez
7b52058265 Add CDB_ForeignTable functions 2016-02-03 17:50:13 +01:00
Javier Goizueta
40a163f885 Release 0.13.1 2016-02-01 19:23:38 +01:00
Javier Goizueta
01d432c22c Merge pull request #193 from CartoDB/fix-multiline-fn
Fix function declaration for create_from_unpackaged.sh use
2016-02-01 19:16:37 +01:00
Javier Goizueta
5285943dbf Fix function declaration for create_from_unpackaged.sh use
The script create_from_unpackaged.sh does not support
function declarations where the signature (name and parameter list
of the function, including parentheses) is not on a single line.
2016-02-01 18:56:55 +01:00
Javier Goizueta
8414bdff31 Release 0.13.0 2016-01-29 17:53:51 +01:00
Javier Goizueta
5f96908df4 Merge pull request #185 from CartoDB/overviews
Overviews (new feature)
2016-01-29 17:44:47 +01:00
Javier Goizueta
06dd31f4ad Fix: should be floating point divistion, not integer division 2016-01-29 16:51:52 +01:00
Javier Goizueta
6a11698a16 Merge branch 'overviews' into sql_lang 2016-01-29 16:29:23 +01:00
Javier Goizueta
00bd302f01 Avoid creating GridCluster overviews for non-point datasets 2016-01-29 16:19:35 +01:00
Javier Goizueta
93d4a6ead0 Restrict SECURITY DEFINER to overview registration
And check it is applied only overview tables with valid names
2016-01-28 17:04:06 +01:00
Javier Goizueta
66387c2d44 Make CDB_CreateOverviews a SECURITY DEFINER function
So that it can change the permissions of overview tables
(by updating pg_class) even when executed by non-priviledeged users.
2016-01-28 16:32:40 +01:00
Javier Goizueta
26c95347cd Merge branch 'master' into overviews 2016-01-27 16:56:15 +01:00
Javier Goizueta
6a5e4b0460 Fix overviews tests
The aggregation method for strings has changed
2016-01-27 16:54:30 +01:00
Javier Goizueta
b8d50204dd Avoid aggregation which causes out-of-memory crashes in PostgreSQL
The use of multiple string_agg functions, even if applied to groups
of one single record causes out of memory crashes in PG 9.3.4 for
some (large) tables.
2016-01-27 15:24:04 +01:00
Alejandro Martínez
845ac6dc9a Release 0.12.0 2016-01-27 14:28:56 +01:00
Alejandro Martínez
350f101c3d Merge pull request #190 from CartoDB/remove_schema_triggers
Remove schema triggers
2016-01-27 14:19:21 +01:00
Javier Goizueta
474de01757 Change the overview table naming scheme
The scheme is changed from table_ovN to _vovw_N_table for
lower collision probability.
Also future naming changes will be easier by using the functions
_CDB_OverviewTableDiscriminator, _CDB_OverviewTableName,
_CDB_IsOverviewTableOf, etc.
2016-01-26 13:20:28 +01:00
Javier Goizueta
1ebaeb76ac Overload CDB_Overviews to accept either a single table or an array
The result of CDB_Overviews has been expandend with a base_table column
2016-01-26 10:39:26 +01:00
Alejandro Martínez
eb1222729d Remove ddl triggers specs 2016-01-21 11:46:39 +01:00
Javier Goizueta
7033a8d9ac Fixes for table names that require quotes or which include a schema name
Some cases left unsolved, with FIXME comments
2016-01-13 18:49:27 +01:00
Javier Goizueta
46bc774d38 Fix CDB_Overviews for the case that the table name requires quoting 2016-01-13 18:24:06 +01:00
Javier Goizueta
a9e2d19918 Document CDB_DropOverviews 2016-01-12 16:20:11 +01:00
Javier Goizueta
d352e1c463 Update Overviews tests 2016-01-12 15:36:07 +01:00
Javier Goizueta
5b47c51221 Add function to drop overviews 2016-01-12 15:35:50 +01:00
Javier Goizueta
ebaded0c7a Merge branch 'master' into overviews 2016-01-12 13:34:26 +01:00
Javier Goizueta
ccdf8de59e Enhance documentation, update comments 2016-01-12 12:08:41 +01:00
Javier Goizueta
a2f6cb4c04 Fix documentation 2016-01-12 11:59:57 +01:00
Javier Goizueta
02f386be33 Regard the GridCluster reduction strategy as private
The *strategy* parameteriation will be considered an
implementation detail for the time being.
2016-01-12 11:59:42 +01:00
Javier Goizueta
a7c70fe497 Fix: CDB_ZoomFromScale deviation for lowest zoom levels 2016-01-12 11:46:47 +01:00
Javier Goizueta
0a066e0126 Change the default overview reduction strategy to GridCluster 2016-01-11 15:35:04 +01:00
Javier Goizueta
913640e2dc Preserve the column ordering of the base table in overviews 2016-01-11 15:34:10 +01:00
Javier Goizueta
ef7e613d41 Change CDB_ColumnNames to order columns names as in table 2016-01-11 15:28:27 +01:00
Javier Goizueta
fd7a8cff71 Change regular expression for consistency 2016-01-11 15:27:05 +01:00
Javier Goizueta
6ea63af974 Add function to obtain existing overviews of a table 2016-01-11 14:50:10 +01:00
Javier Goizueta
496f079b1c Copy dataset privileges to overview tables 2016-01-04 18:06:56 +01:00
Javier Goizueta
4580c9cd5c Change the cartodb_ids of aggregated overviews
Instead of arbitrary ids, the id of one of the aggregated records
is used, so that if it is used in the UI to query point
the information of one of the records grouped at the point will be
retrieved.
2016-01-04 10:33:39 +01:00
Javier Goizueta
08828b8b7d Set owner of overlays to the owner of the base table 2015-12-29 15:22:12 +01:00
Javier Goizueta
cecba655eb Preserve aggregated attributes of singleton groups 2015-12-29 14:56:47 +01:00
Javier Goizueta
b34a752172 Generate overviews for all Z levels
Skipping levels produces visually inferior results
2015-12-29 14:56:04 +01:00
Javier Goizueta
8ba9e74c4a Order columns of aggregated overlays as in the base table 2015-12-29 13:38:07 +01:00
Alejandro Martínez
045ede6908 Remove schema_triggers from travis.yml 2015-12-29 10:43:37 +01:00
Alejandro Martínez
cd5c8f2904 Remove outdated references to schema triggers and change triggers 2015-12-29 10:43:18 +01:00
Alejandro Martínez
172ca45ea5 Merge remote-tracking branch 'origin/master' into remove_schema_triggers 2015-12-29 10:41:13 +01:00
Javier Goizueta
6a6a5bc96a Fix Sampling reduction to avoid RandomTids problems
The fixed cases will not be common but do occur in tests.
This is an interim fix which should be reverted if CDB_randomTids changes.
2015-12-28 19:41:14 +01:00
Javier Goizueta
2ff686de27 Clean up: remove spurious comment 2015-12-28 19:30:20 +01:00
Javier Goizueta
07326626b7 More efficient sampling strategy
It is also renamed properly.
2015-12-28 19:28:20 +01:00
Javier Goizueta
4afc427008 Rename Ref. Z strategy function
It's not that *dummy* anymore, so choose a more descriptive name
2015-12-28 17:47:57 +01:00
Paul Norman
2ab059460b Merge pull request #189 from pnorman/fix_travis
Fix test errors on Travis
2015-12-23 10:56:56 -08:00
Alejandro Martínez
2a2a7d534a Merge remote-tracking branch 'origin/master' into remove_schema_triggers 2015-12-23 17:09:41 +01:00
Javier Goizueta
8d1bbc63fa Add overview tests 2015-12-23 16:33:34 +01:00
Javier Goizueta
06ca4f74ee Enable Overviews module in the extension 2015-12-23 16:32:44 +01:00
Javier Goizueta
a8a2c04d71 Remove invalid comment 2015-12-23 14:20:57 +01:00
Javier Goizueta
a5bca7d715 Add function for post-processing new overview tables 2015-12-23 14:17:50 +01:00
Javier Goizueta
552206464e Make strategy function public 2015-12-23 12:50:04 +01:00
Javier Goizueta
2af0b9a57f Add function comments 2015-12-23 12:42:40 +01:00
Javier Goizueta
1b5de84c9a Add missing attribute-aggregationto the point reduction strategy 2015-12-23 12:17:37 +01:00
Paul Norman
3b48acf60c Round extent outputs in test
Travis was reporting rounded results, so this should make the behavior more consistent
2015-12-22 16:34:18 -08:00
Paul Norman
efb319074a Add constraint to QueryTablesTest 2015-12-22 16:21:54 -08:00
Javier Goizueta
c36a5d35c3 Merge branch 'overviews' of github.com:CartoDB/cartodb-postgresql into overviews 2015-12-22 18:02:16 +01:00
Javier Goizueta
5a78ee2896 Optimize the gridded clustering strategy
The internal grid_px parameter is adjusted for best results with default symbol size
2015-12-22 17:59:49 +01:00
Rafa de la Torre
480e2d0979 Merge pull request #187 from CartoDB/overviews-rtorre
Overviews rtorre touches
2015-12-22 17:45:14 +01:00
Javier Goizueta
c8a1ef6f68 Slight optimization of gridded clustering 2015-12-22 15:25:21 +01:00
Paul Norman
ea7c16fbaf Convert some simple functions from plpgsql to sql
SQL is a faster language to call, and these are very simple functions.
2015-12-21 23:59:26 -08:00
Rafa de la Torre
564ab75d2d Use _cdb_estimated_extent instead of ST_Extent
With a 3.8M points table, this was a ~30% gain in my local env.
2015-12-21 18:41:50 +01:00
Rafa de la Torre
5010109c7d Add _cdb_estimated_extent to get the extent from stats 2015-12-21 18:41:45 +01:00
Paul Norman
a9f6e26fed Merge pull request #184 from pnorman/readme_url
Update wiki URL
2015-12-21 08:35:01 -08:00
Rafa de la Torre
e60f73a31b A bit of internal documentation 2015-12-21 13:16:57 +01:00
Javier Goizueta
415a09392f Gridded clustering aggregation strategy for overviews 2015-12-16 17:45:36 +01:00
Javier Goizueta
e5cc9ef0bd Fix: typo 2015-12-16 17:26:17 +01:00
Javier Goizueta
f7857945c1 Change feature density computation algorithm
Now parameterize by the number of levels to traverse and
start with the level that covers the extent of the table
with at least N*N tiles (N=4).
2015-12-16 16:39:38 +01:00
Javier Goizueta
554464e43e Use tile-recursive computation of feature density
This is a more adaptive way of estimating the feature density to
determine the base Z level.
Applying technique from http://javisantana.com/2014/10/22/traversing-quadtree.html
2015-12-16 12:14:37 +01:00
Javier Goizueta
d7c8f3d7e8 Fix: overlay generation was not using the proper scale 2015-12-15 19:13:39 +01:00
Javier Goizueta
4c85d7f3ad Compute the reference Z level for a table 2015-12-15 19:12:48 +01:00
Javier Goizueta
d0e66910a0 Sketch for new Overview-creation functionality 2015-12-15 17:36:27 +01:00
Paul Norman
dcf0b684e2 Update wiki URL 2015-12-08 10:08:17 -08:00
Stuart Lynn
0ecbbd8e71 Make sure that empty arrays or arrays with all the same entry return 0 for Skewness and Kurtosis rather than throwing a division by zero error 2015-12-04 14:54:15 -05:00
Javier Goizueta
a88bfc51a3 Upgrade version to 0.11.5 2015-11-27 17:03:51 +01:00
Javier Goizueta
21d5ee5813 Merge pull request #178 from CartoDB/disable-log-invalidation-time
Disable log invalidation time
2015-11-27 15:03:46 +01:00
Luis Bosque
d39a032024 Revert "Write invalidation duration in postgresql log"
This reverts commit 37160c7b35.
2015-11-17 13:10:19 +01:00
Luis Bosque
4cceb2a21f Revert "Optimize invalidation time logging"
This reverts commit d1d5ed6df3.
2015-11-17 13:10:15 +01:00
Alejandro Martínez
2a8d467949 Merge remote-tracking branch 'origin/master' into remove_schema_triggers 2015-11-05 14:49:46 +01:00
Alejandro Martínez
8895d9f3af Remove DDL from Makefile 2015-11-04 17:26:38 +01:00
Alejandro Martínez
ef376fd243 Remove schema_triggers 2015-11-04 17:06:54 +01:00
102 changed files with 5602 additions and 1221 deletions

View File

@@ -1,22 +1,43 @@
language: c
dist: precise
sudo: required
addons:
postgresql: 9.3
postgresql: 9.5
before_install:
# Add custom PPAs from cartodb
- sudo add-apt-repository -y ppa:cartodb/postgresql-9.5
- sudo add-apt-repository -y ppa:cartodb/gis
- sudo add-apt-repository -y ppa:cartodb/gis-testing
- sudo apt-get update
#- sudo apt-get install -q postgresql-9.3-postgis-2.1
- sudo apt-get update
- sudo apt-get install -q postgresql-server-dev-9.3
- sudo apt-get install -q postgresql-plpython-9.3
# Install schema_triggers
- hg clone https://bitbucket.org/malloclabs/pg_schema_triggers &&
cd pg_schema_triggers && make && sudo make install && cd -
# Preload schema_triggers module
# NOTE: might change if we make it part of the installcheck instead
- echo "shared_preload_libraries = 'schema_triggers.so'" |
sudo tee -a /etc/postgresql/9.3/main/postgresql.conf &&
sudo service postgresql restart
# Force instalation of libgeos-3.5.0 (presumably needed because of existing version of postgis)
- sudo apt-get -y install libgeos-3.5.0=3.5.0-1cdb2
# Install postgres db and build deps
- sudo /etc/init.d/postgresql stop # stop travis default instance
- sudo apt-get -y remove --purge postgresql-9.1
- sudo apt-get -y remove --purge postgresql-9.2
- sudo apt-get -y remove --purge postgresql-9.3
- sudo apt-get -y remove --purge postgresql-9.4
- sudo apt-get -y remove --purge postgresql-9.5
- sudo rm -rf /var/lib/postgresql/
- sudo rm -rf /var/log/postgresql/
- sudo rm -rf /etc/postgresql/
- sudo apt-get -y remove --purge postgis-2.2
- sudo apt-get -y autoremove
- sudo apt-get -y install postgresql-9.5=9.5.2-3cdb3
- sudo apt-get -y install postgresql-server-dev-9.5=9.5.2-3cdb3
- sudo apt-get -y install postgresql-plpython-9.5=9.5.2-3cdb3
- sudo apt-get -y install postgresql-9.5-postgis-scripts=2.2.2.0-cdb2
- sudo apt-get -y install postgresql-9.5-postgis-2.2=2.2.2.0-cdb2
# configure it to accept local connections from postgres
- echo -e "# TYPE DATABASE USER ADDRESS METHOD \nlocal all postgres trust\nlocal all all trust\nhost all all 127.0.0.1/32 trust" \
| sudo tee /etc/postgresql/9.5/main/pg_hba.conf
- sudo /etc/init.d/postgresql restart 9.5
script:
- make

View File

@@ -22,13 +22,19 @@ and upgrade of the objects. This means using CREATE OR REPLACE for
the functions, and whatever it takes to check existence of any previous
version of objects in other cases.
When adding a new function or modifying an exiting one make sure that the
[VOLATILITY](https://www.postgresql.org/docs/current/static/xfunc-volatility.html) and [PARALLEL](https://www.postgresql.org/docs/9.6/static/parallel-safety.html) categories are updated accordingly.
As PARALLEL labels need to be stripped for incompatible PostgreSQL versions
please use _PARALLEL SAFE/RESTRICTED/UNSAFE_ in uppercase so it's handled
automatically.
When used as an extension (probably always from version 0.2.0 onwards)
all the objects will be installed in a "cartodb" schema. Take this into
account to fully-qualify internal calls to avoid (possibly dangerous)
name clashes.
Every new feature (as well as bugfixes) should come with a test case,
see next section.
see the 'Writing testcases' section.
Writing testcases
-----------------
@@ -62,3 +68,7 @@ A useful query:
```sql
SELECT * FROM pg_extension_update_paths('cartodb') WHERE path IS NOT NULL AND source = cdb_version();
```
## Submitting Contributions
* You will need to sign a Contributor License Agreement (CLA) before making a submission. [Learn more here](https://carto.com/contributions).

View File

@@ -1,14 +1,14 @@
# cartodb/Makefile
EXTENSION = cartodb
EXTVERSION = 0.11.4
EXTVERSION = 0.22.0
SED = sed
AWK = awk
CDBSCRIPTS = \
scripts-enabled/*.sql \
scripts-available/CDB_SearchPath.sql \
scripts-available/CDB_DDLTriggers.sql \
scripts-available/CDB_ExtensionPost.sql \
scripts-available/CDB_ExtensionUtils.sql \
scripts-available/CDB_Helper.sql \
@@ -56,6 +56,36 @@ UPGRADABLE = \
0.11.2 \
0.11.3 \
0.11.4 \
0.11.5 \
0.12.0 \
0.13.0 \
0.13.1 \
0.14.0 \
0.14.1 \
0.14.2 \
0.14.3 \
0.14.4 \
0.15.0 \
0.15.1 \
0.16.0 \
0.16.1 \
0.16.2 \
0.16.3 \
0.16.4 \
0.17.0 \
0.17.1 \
0.18.0 \
0.18.1 \
0.18.2 \
0.18.3 \
0.18.4 \
0.18.5 \
0.19.0 \
0.19.1 \
0.19.2 \
0.20.0 \
0.21.0 \
0.22.0 \
$(EXTVERSION)dev \
$(EXTVERSION)next \
$(END)
@@ -77,22 +107,30 @@ DATA_built = \
EXTRA_CLEAN = cartodb_version.sql
DOCS = README.md
REGRESS_NEW = test_ddl_triggers
REGRESS_OLD = $(wildcard test/*.sql)
REGRESS_LEGACY = $(REGRESS_OLD:.sql=)
REGRESS = test_setup $(REGRESS_NEW) $(REGRESS_LEGACY)
REGRESS = test_setup $(REGRESS_LEGACY)
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
PG_PARALLEL := $(shell $(PG_CONFIG) --version | ($(AWK) '{$$2*=1000; if ($$2 >= 9600) print 1; else print 0;}' 2> /dev/null || echo 0))
include $(PGXS)
$(EXTENSION)--$(EXTVERSION).sql: $(CDBSCRIPTS) cartodb_version.sql Makefile
$(EXTENSION)--$(EXTVERSION).sql: $(CDBSCRIPTS) cartodb_version.sql Makefile
echo '\echo Use "CREATE EXTENSION $(EXTENSION)" to load this file. \quit' > $@
cat $(CDBSCRIPTS) | \
$(SED) -e 's/public\./cartodb./g' \
-e 's/:DATABASE_USERNAME/cdb_org_admin/g' >> $@
$(SED) -e 's/public\./cartodb./g' \
-e 's/:DATABASE_USERNAME/cdb_org_admin/g' \
-e "s/''public''/''cartodb''/g" >> $@
echo "GRANT USAGE ON SCHEMA cartodb TO public;" >> $@
cat cartodb_version.sql >> $@
ifeq ($(PG_PARALLEL), 0)
# Remove PARALLEL in aggregates and functions
$(eval TMPFILE := $(shell mktemp /tmp/$(basename $0).XXXXXXXX))
$(SED) -e 's/PARALLEL \= [A-Z]*,/''/g' \
-e 's/PARALLEL [A-Z]*/''/g' $@ > $(TMPFILE)
mv $(TMPFILE) $@
endif
$(EXTENSION)--unpackaged--$(EXTVERSION).sql: $(EXTENSION)--$(EXTVERSION).sql util/create_from_unpackaged.sh Makefile
./util/create_from_unpackaged.sh $(EXTVERSION)
@@ -105,27 +143,33 @@ $(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql: $(EXTENSION)--$(EXTVERSION).
$(EXTENSION).control: $(EXTENSION).control.in Makefile
$(SED) -e 's/@@VERSION@@/$(EXTVERSION)/' $< > $@
ifeq ($(PG_PARALLEL), 0)
echo -e "\033[0;31mExtension created without PARALLEL support\033[0m"
endif
cartodb_version.sql: cartodb_version.sql.in Makefile $(GITDIR)/index
$(SED) -e 's/@@VERSION@@/$(EXTVERSION)/' $< > $@
# Needed for consistent `echo` results with backslashes
SHELL = bash
legacy_regress: $(REGRESS_OLD) Makefile
mkdir -p sql/test/
mkdir -p expected/test/
mkdir -p results/test/
for f in $(REGRESS_OLD); do \
tn=`basename $${f} .sql`; \
of=sql/test/$${tn}.sql; \
echo '\\set ECHO none' > $${of}; \
echo '\\a' >> $${of}; \
echo '\\t' >> $${of}; \
echo '\\set QUIET off' >> $${of}; \
cat $${f} | \
$(SED) -e 's/public\./cartodb./g' >> $${of}; \
exp=expected/test/$${tn}.out; \
echo '\\set ECHO none' > $${exp}; \
cat test/$${tn}_expect >> $${exp}; \
done
tn=`basename $${f} .sql`; \
of=sql/test/$${tn}.sql; \
echo '\set ECHO none' > $${of}; \
echo '\a' >> $${of}; \
echo '\t' >> $${of}; \
echo '\set QUIET off' >> $${of}; \
cat $${f} | \
$(SED) -e 's/public\./cartodb./g' >> $${of}; \
exp=expected/test/$${tn}.out; \
echo '\set ECHO none' > $${exp}; \
cat test/$${tn}_expect >> $${exp}; \
done
test_organization:
bash test/organization/test.sh
@@ -133,7 +177,7 @@ test_organization:
test_extension_new:
bash test/extension/test.sh
legacy_tests: legacy_regress
legacy_tests: legacy_regress
installcheck: legacy_tests test_extension_new test_organization

180
NEWS.md
View File

@@ -1,8 +1,186 @@
0.22.0 (2018-03-22)
* Fix: allow older ogr2ogr to work in -append mode (#319,#325)
* Refactors CDB_QuantileBins to rely on PostgreSQL function `percentile_disc` #316
0.21.0 (2018-02-15)
* Add optional parameter to limit the number of cells in grid-generation functions #322
* Fix: grant usage on cartodb_id sequence when sharing read write #323
* Fix: Change sed in-place for tmpfiles 524319
0.20.0 (2017-11-08)
* Added VOLATILITY and PARALLEL categories to all functions
0.19.2 (2017-06-30)
* Improved functions to generate unique identifiers #305
0.19.1 (2017-06-05)
* Fixed a deadlock problem when trying to regenarate overviews #302
0.19.0 (2017-04-11)
* Add new function `CDB_EstimateRowCount` #295
0.18.5 (2016-11-30)
* Add to new overview creation strategies #290
* Fix tests: race condition with publicuser #157
* Fix: CDB_Stats divisions by zero #181
* Better implementation of `CDB_EqualIntervalBins` #244
* New tests for binning functions #249
0.18.4 (2016-11-04)
* No functional changes; fixes the migration from previous versions #288
0.18.3 (2016-11-03)
* Exclude analysis cache tables from the quota #281
0.18.2 (2016-10-20)
-------------------
* Fix: cleanup inconsistent position of `username` column in analysis catalog after upgrades
[#285](https://github.com/cartodb/cartodb-postgresql/pull/285)
0.18.1 (2016-10-19)
-------------------
* Increase analysis limit factor to 2 [#284](https://github.com/CartoDB/cartodb-postgresql/pull/284)
0.18.0 (2016-10-17)
-------------------
* Fix: exclude NULL geometries when creating Overviews #269
* Function to check analysis tables limits #279
0.17.1 (2016-08-16)
-------------------
* Add cache_tables column to cdb_analysis_catalog table #274.
0.17.0 (2016-07-04)
-------------------
* Add export config for cdb_analysis_catalog table #268.
* Add some extra fields to cdb_analysis_catalog table. Track user, error_message for failures, and last entity modifying the node #267.
* Exclude overviews from user data size #262.
0.16.4 (2016-05-27)
-------------------
* Change CDB_ZoomFromScale() to use a formula and raise
maximum overview level from 23 to 29.
[#259](https://github.com/CartoDB/cartodb-postgresql/pull/259)
* Fix bug in overview creating causing it to fail when `x` or
`y` columns exist with non-integer type. Prevent also
potential integer overflows limiting maximum overview level
to 23.
[#258](https://github.com/CartoDB/cartodb-postgresql/pull/258)
0.16.3 (2016-05-09)
-------------------
* Fix overview creation problem for organization users
with names that require quoting:
[#253](https://github.com/CartoDB/cartodb-postgresql/pull/253)
0.16.2 (2016-04-27)
-------------------
* Use the mode to aggregate category columns in overviews
[#246](https://github.com/CartoDB/cartodb-postgresql/pull/246)
0.16.1 (2016-04-25)
-------------------
* Optimize column information functions performance
[#238](https://github.com/CartoDB/cartodb-postgresql/pull/238)
* Adjust overview points to pixel CDB_EqualIntervalBins
[#242](https://github.com/CartoDB/cartodb-postgresql/pull/242)
* Compute webmercator resolution using full numeric precision
[#243](https://github.com/CartoDB/cartodb-postgresql/pull/243)
0.16.0 (2016-04-15)
-------------------
* Adds table for storing camshaft analysis nodes
[#237](https://github.com/CartoDB/cartodb-postgresql/pull/237)
0.15.1 (2016-04-15)
-------------------
* Fix problems with org users in overviews functions
[#224](https://github.com/CartoDB/cartodb-postgresql/pull/224)
* Add `_feature_count` to overviews
[#227](https://github.com/CartoDB/cartodb-postgresql/pull/227)
* Change point clustering behaviour of overviews
[#228](https://github.com/CartoDB/cartodb-postgresql/pull/228)
* Change default tolerance of overviews
[#230](https://github.com/CartoDB/cartodb-postgresql/pull/230)
* Fix problem with aggregated numerical fields in overviews
[#233](https://github.com/CartoDB/cartodb-postgresql/pull/233)
* Enhance aggregation of text fields in overviews
[#234]https://github.com/CartoDB/cartodb-postgresql/pull/234
0.15.0 (2016-04-05)
-------------------
* New function CDB_CreateOverviewsWithToleranceInPixels that adds tolerance parameter for overview creation
[#221](https://github.com/CartoDB/cartodb-postgresql/pull/221)
* New default value for the overviews tolerance in pixels is 2 (used to be 7.5) (also in #221)
* The feature density limit used to choose the reference Z level now depends on the tolerance in pixels (also in #221)
* Tables that require an explicit schema can now be passed to overview functions
[#220](https://github.com/CartoDB/cartodb-postgresql/pull/220)
0.14.4 (2016-03-29)
-------------------
* Fix creating overviews for tables with boolean columns
[#214](https://github.com/CartoDB/cartodb-postgresql/pull/214)
* Fix tests for some systems [#215](https://github.com/CartoDB/cartodb-postgresql/pull/215)
0.14.3 (2016-03-17)
-------------------
* Fix for `cartodb_id` bigint casting hardcoded in 0.14.2 to support `cartodb_id` text columns [#210](https://github.com/CartoDB/cartodb-postgresql/pull/210)
0.14.2 (2016-03-15)
-------------------
* Support text `cartodb_id` columns in `_CDB_Has_Usable_Primary_ID` [#202](https://github.com/CartoDB/cartodb-postgresql/pull/202)
0.14.1 (2016-03-07)
-------------------
* Fully qualify table names in cache cdb_invalidate_varnish calls [#198](https://github.com/CartoDB/cartodb-postgresql/issues/198)
0.14.0 (2016-02-14)
-------------------
* Add CDB_ForeignTable.sql to support FDW's [#199](https://github.com/CartoDB/cartodb-postgresql/pull/199)
0.13.1 (2016-02-01)
-------------------
* Fix migration fron unpackaged. [193](https://github.com/CartoDB/cartodb-postgresql/pull/193)
0.13.0 (2016-01-29)
-------------------
* Add CDB_CreateOverviews, CDB_DropOverviews and CDB_Overviews for vector overviews support. [185](https://github.com/CartoDB/cartodb-postgresql/pull/185)
* Convert some simple functions from plpgsql to sql. [188](https://github.com/CartoDB/cartodb-postgresql/pull/188)
0.12.0 (2016-01-27)
-------------------
* Remove schema_triggers extension dependency, to ensure compatibility with PostgreSQL 9.5. [#190](https://github.com/CartoDB/cartodb-postgresql/pull/190)
* Remove DDL trigger functions (unused by CartoDB).
0.11.5 (2015-11-27)
-------------------
* Disable log invalidation time [#178](https://github.com/CartoDB/cartodb-postgresql/pull/178)
0.11.4 (2015-11-24)
-------------------
* Fix for existing PK cartodb_id problem [#174](https://github.com/CartoDB/cartodb-postgresql/issues/174)
* Add cartodbfication support for column names with embedded points to fix [#6114](https://github.com/CartoDB/cartodb/issues/6114)
* Disable log invalidation time [#178](https://github.com/CartoDB/cartodb-postgresql/pull/178)
* Add CDB_GreatCircle for creating great circle routes between two points [#171](https://github.com/CartoDB/cartodb-postgresql/pull/171)
* Fix to prevent cartodbfication problems [#155](https://github.com/CartoDB/cartodb-postgresql/issues/155)

View File

@@ -1,21 +1,17 @@
cartodb-postgresql
==================
[![Build Status](http://travis-ci.org/CartoDB/cartodb-postgresql.png)]
(http://travis-ci.org/CartoDB/cartodb-postgresql)
[![Build Status](http://api.travis-ci.org/CartoDB/cartodb-postgresql.svg?branch=master)](http://travis-ci.org/CartoDB/cartodb-postgresql)
PostgreSQL extension for CartoDB
See https://github.com/CartoDB/cartodb/wiki/CartoDB-PostgreSQL-extension
See [the cartodb-postgresql wiki](https://github.com/CartoDB/cartodb-postgresql/wiki).
Dependencies
------------
* PostgreSQL 9.3+ (with plpythonu extension and xml support)
* [PostGIS extension](http://postgis.net)
* [Schema triggers extension]
(https://bitbucket.org/malloclabs/pg_schema_triggers)
(or [fork](https://github.com/CartoDB/pg_schema_triggers))
Install
-------
@@ -31,10 +27,6 @@ Test installation
make installcheck
```
NOTE: if ``test_ddl_triggers`` fails it's likely due to an incomplete
installation of schema_triggers: you need to add ``schema_triggers.so``
to the ``shared_preload_libraries`` setting in postgresql.conf !
NOTE: you need to run the installcheck as a superuser, use PGUSER
env variable if needed, like: PGUSER=postgres make installcheck
@@ -47,7 +39,6 @@ In a database that needs to be turned into a "cartodb" user database, run:
```sql
CREATE EXTENSION postgis;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION cartodb;
```
@@ -63,7 +54,6 @@ be in the "cartodb" schema.
```sql
CREATE EXTENSION postgis FROM unpackaged;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION cartodb FROM unpackaged;
```

View File

@@ -3,4 +3,4 @@ comment = 'Turn a database into a cartodb user database.'
superuser = true
relocatable = false
schema = cartodb
requires = 'plpythonu, schema_triggers, postgis'
requires = 'plpythonu, postgis'

View File

@@ -0,0 +1,25 @@
Estimate the number of rows of a query.
#### Using the function
```sql
SELECT CDB_EstimateRowCount($$
UPDATE addresses SET the_geom = cdb_geocode_street_point(addr, city, state, 'US');
$$) AS row_count;
```
Result:
```
row_count
-----------
5
(1 row)
```
#### Arguments
CDB_EstimateRowCount(query)
* **query** text: the SQL query to estimate the row count for.

123
doc/CDB_Overviews.md Normal file
View File

@@ -0,0 +1,123 @@
Overviews are tables that represent a *reduced* version of a dataset intended
for efficient rendering at certain zoom levels while preserving the
general visual appearance of the complete dataset.
The *reduction* consists in havig a fewer number of records
(while each overview record may represent an aggregation of multiple records)
and/or simplified record geometries.
Overviews are created through the `CDB_CreateOverviews` function.
The statement timeout may need to be adjusted before using this function,
as overview creation for large tables is a time-consuming operation.
The `CDB_Overviews` function can be used determine what overview tables
exist for a given dataset table and which zoom levels correspond to it.
The `CDB_DropOverviews` function removes a dataset's existing overviews.
To know if overview tables exist for some base table, and to obtain
a list of which overview tables are approrpiate for which zoom levels,
the `CDB_Overviews` functions can be used.
The zoom level we're referring here to are those used
by the tiler: http://wiki.openstreetmap.org/wiki/Zoom_levels
### CDB_CreateOverviews
Create overviews for vector dataset.
#### Using the function
The table for which overviews will be generated should be
a Cartodbfied dataset with vector geometry.
```sql
SELECT CDB_CreateOverviews('table_name');
--- Generates overview tables for the dataset
```
#### Arguments
CDB_CreateOverviews(table_name, ref_z_strategy, reduction_strategy)
* **table_name** regclass, table for which overviews will be generated
* **ref_z_strategy** regproc, optional function that provides
the Z-scale strategy.
It returns the base Z level for the dataset.
It should have these arguments:
- **table_name** regclass, table to compute the reference Z scale for
* **reduction_strategy** regproc, optional function that provides
the reduction strategy to generate an overview table from a table
for a smaller scale (higher Z number).
It returns the name of the generated table.
It should have these arguments:
- **base_table_name** regclass, base table to be reduced.
- **base_z** integer, base Z level assigned to the base table.
- **overview_z** integer, Z level for which to generate the overview.
#### Tolerance / level of detail
The level of detail to be representable by each overview layer can
be specified as a tolerance in pixels (if different from the default of 1 pixel)
with the function `CDB_CreateOverviewsWithToleranceInPixels`
which has as a second additional argument the desired tolerance.
This tolerance defines the maximum deviation in pixels of the overviews
geometries with respect to the original geometries when overview tables
are used for their intendend zoom level.
### CDB_Overviews
Obtain overview metadata for a given table (existing overviews).
The returned relation will be empty if the table has no overviews.
The function can be applied to a single table:
```sql
SELECT CDB_Overviews('table_name');
--- Return existing overview Z levels and corresponding tables
```
Or to multiple tables passed as an array; this can be used
to obtain the overviews that can be applied to a query by
combining it with `CDB_QueryTablesText`:
```sql
SELECT CDB_Overviews(CDB_QueryTablesText('SELECT * FROM table1, table2'));
--- Return existing overview Z levels and corresponding tables
```
The result of `CDB_Overviews` has three columns:
| base_table | z | overview_table |
| ---------- | - | -------------- |
| table1 | 1 | table1_ov1 |
| table1 | 2 | table1_ov2 |
| table1 | 4 | table1_ov4 |
| table2 | 1 | table1_ov1 |
| table2 | 2 | table1_ov2 |
#### Arguments
CDB_Overviews(table_name)
* **table_name** regclass, oid of table to obtain existing overviews for
CDB_Overviews(table_names)
* **table_names** regclass[], array of table oids
### CDB_DropOverviews
Remove the overviews of a table, if present.
```sql
SELECT CDB_DropOverviews('table_name');
```
#### Arguments
CDB_Overviews(table_name)
* **table_name** regclass, table for which to drop existing overviews.

View File

@@ -3,7 +3,11 @@ List the name of available tables (only the usable ones)
#### Using the function
```sql
--- Returns a row for each table having given permission with the table name
--- Returns a row for each table having given permission with the table name.
--- It also returns tables from others users if you've permission to see them. For example, consider the following scenario:
--- User X and User Y at account C.
--- User X has a public table T.
--- User Y will see table T.
--- Currently accepted permissions are: 'public', 'private' or 'all'
SELECT CDB_UserTables(perms)
```

View File

@@ -1,29 +0,0 @@
A "cartodb" user table is a table with a well-known set of fields and a well-known set of triggers attached on.
The fields are:
- `cartodb_id`, a numerical primary key of serial type
- `created_at`, timestamp with timezone not null default now()
- `updated_at`, timestamp with timezone not null default now()
- `the_geom`, geometry, GiST indexed, constrained (see below)
- `the_geom_webmercator`, geometry, GiST indexed, constrained (see below)
The values of "the_geom" and "the_geom_webmercator" must match these constraints:
- Only POINT, MULTILINE, MULTIPOLYGON types ? Maybe UNCONSTRAINED
- Only 2 dimensions ? Maybe UNCONSTRAINED
- SRID=4326 for the_geom and SRID=3857 for the_geom_webmercator
The triggers are:
- `track_updates` after modifying statement updates cdb_tablemetadata
- `test_quota` before changing statement to forbid if overquota
- `test_quota_per_row` before changing row to forbod if overquota (checked on a probabilistic basis)
- `update_the_geom_webmercator` before insert or update row to maintain the_geom_webmercator
- `update_updated_at_trigger` before update row to maintain updated_at
Some conversions will be attempted to perform upon cartodbfication when certain fields appear:
- `cartodb_id`: If found type TEXT will be attempted to cast
- `created_at`: If found type TEXT will be attempted to cast
- `updated_at`: If found type TEXT will be attempted to cast

View File

@@ -0,0 +1,68 @@
CartoDB User Table
==================
Introduction
----------
A CartoDB user table is a table with a well-known set of columns and a well-known set of triggers attached on.
Columns
----------
The required columns of a CartoDB table are:
- ``cartodb_id``
- This column will be used as the primary key of the table and it has a sequence as default value
- Its values must be integer, non-zero, non-null and unique
- B-Tree indexed
- ``the_geom``
- This column stores the main geometric features of a table
- The type of the column in the Postgres database is ``geometry(Geometry,4326)```
- GiST indexed
- geometry, GiST indexed, constrained (see below)
- ``the_geom_webmercator``
- This column stores the geometries used for rendering purposes
- The type of the column in the Postgres database is ``geometry(Geometry,3857)``
- GiST indexed
- This column is automatically updated by the system when the ``the_geom`` column is updated or when there is an insertion of a new row into the table (See triggers below)
The values of ``the_geom`` and ``the_geom_webmercator`` must be two-dimensional Points, MultiLineStrings or MultiPolygons. Different geometric types in a CartoDB table are not supported.
Described table example
^^^^^^^^^^
::
Column | Type | Modifiers
----------------------+-------------------------+--------------------------------------------------------
cartodb_id | bigint | not null default nextval('t_cartodb_id_seq'::regclass)
the_geom | geometry(Geometry,4326) |
the_geom_webmercator | geometry(Geometry,3857) |
Indexes:
"table_name_pkey" PRIMARY KEY, btree (cartodb_id)
"table_name_the_geom_idx" gist (the_geom)
"table_name_the_geom_webmercator_idx" gist (the_geom_webmercator)
Triggers
----------
The triggers generated in each CartoDB table are:
- ``track_updates`` after modifying statement updates ``cdb_tablemetadata``
- ``test_quota`` before changing statement to forbid if overquota
- ``test_quota_per_row`` before insert ot update row to forbid if overquota (checked on a probabilistic basis)
- ``update_the_geom_webmercator`` before insert or update row to maintain the ``the_geom_webmercator`` updated with the contents in ``the_geom``
Described triggers example
^^^^^^^^^^
::
test_quota BEFORE INSERT OR UPDATE ON t FOR EACH STATEMENT EXECUTE PROCEDURE cdb_checkquota('0.1', '-1', 'public')
test_quota_per_row BEFORE INSERT OR UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE cdb_checkquota('0.001', '-1', 'public')
track_updates AFTER INSERT OR DELETE OR UPDATE OR TRUNCATE ON t FOR EACH STATEMENT EXECUTE PROCEDURE cdb_tablemetadata_trigger()
update_the_geom_webmercator_trigger BEFORE INSERT OR UPDATE OF the_geom ON t FOR EACH ROW EXECUTE PROCEDURE _cdb_update_the_geom_webmercator()
Further details
----------
Some conversions will be attempted to perform upon cartodbfication when certain fields appear:
- ``cartodb_id``: If found type TEXT will be attempted to cast to integer. If not casteable, an eror will be raised.
- ``the_geom``: If found type TEXT will be attempted to cast to geometry(Geometry,4326).

View File

@@ -20,29 +20,4 @@ The CartoDB PostgreSQL extension is a module to load into each CartoDB user data
# Checks
No user other than the superuser should be allowed to change `statement_timeout` for the session (SET statement_timeout disallowed).
User tables need to match certain structure criteria (See [[CartoDB-user-table]]) so the extension should provide a mean to enforce such structure everytime an attempt to change structure is encountered.
# Events
The events we want some function to be called upon are:
| event | arguments to handler function | function duty | OK* |
|------------------------|--------------------------------------|----------------------------------|-----|
| SET variable | name of variable | forbid changing some vars | |
| RENAME table | old and new name + oid of the table | flush cache | |
| ADD/DROP/ALTER column | oid of the table | flush cache, cartodbfy, upd meta | Y |
| DISABLE/DROP trigger | oid of table, name of trigger | cartodbfy or forbid | |
| DROP table | oid of the table | flush cache and metadata | Y |
| CREATE table | oid of the table | cartodby, upd metadata | Y |
| GRANT | oid of table, privilege, role | flush cache, upd metadata |
| REVOKE | oid of table, privilege, role | flush cache, upd metadata |
* event available by installing https://github.com/CartoDB/pg_schema_triggers
At this stage we don't need more than this, but the number of events and the number of arguments passed to the handler function may expand in the future, so the extension should be written in a way to easily allow that.
Some of the handler will need to act _after_ the statement is completed (CREATE TABLE, for example).

View File

@@ -1,59 +1,63 @@
CartoDBfy Requirements
======================
Introduction
============
------------
This document aims at describing what cartodbfy is and what its formal requirements are, with the following goals in mind:
This document aims at describing what the CartoDBfication is and what its formal requirements are, with the following goals in mind:
- clarify what are the expectations of the "cartodbfycation process".
- define an important part of what should be a stable, public API
- allow for better testing, which should in turn...
- Clarify what are the expectations of the "cartodbfycation process".
- Define an important part of what should be a stable, public API
- Allow for better testing, which should in turn...
- ...ease modifications and increase quality of the code
What is the CartoDBfycation
---------------------------
What is the cartodbfycation
===========================
The cartodbfycation is the process of converting an arbitrary postgres table into a valid CartoDB table, and register it in the system so that it can be used in the CartoDB editor and platform to generate maps and analysis.
The CartoDBfycation is the process of converting an arbitrary postgres table into a valid CartoDB table, and register it in the system so that it can be used in the CartoDB editor and platform to generate maps and analysis.
It is performed by running the function ``CDB_CartodbfyTable(reloid REGCLASS)`` over a target table.
Valid CartoDB tables
====================
--------------------
A valid CartoDB table shall meet the following conditions:
- Have a ``cartodb_id`` integer column as primary key with a sequence as default value
- Have a ``cartodb_id`` column with integer, unique, non-zero and non-null values as primary key with a sequence as default value
- Have a ``the_geom`` column of type ``Geometry`` with SRID 4326
- Have a ``the_geom_webmercator`` column of type ``Geometry`` with SRID 3857
- The columns ``the_geom`` and ``the_geom_webmercator`` shall be in sync
- The columns ``the_geom`` and ``the_geom_webmercator`` shall be in sync (task of the ``update_the_geom_webmercator`` trigger)
Additionally, a CartoDB table can contain other columns.
See the `CartoDB User Table documentation`_
.. _CartoDB User Table documentation: https://github.com/CartoDB/cartodb-postgresql/blob/master/doc/CartoDB-user-table.rst
for further information.
High level requirements
=======================
-----------------------
Here is a list of high level requirments for the public function ``CDB_CartodbfyTable()``:
- A call to ``CDB_CartodbfyTable()`` shall modify/rewrite the table and produce a valid CartoDB table with the same name.
- A call to ``CDB_CartodbfyTable()`` shall cause the registration of the table into the platform
- It shall be idempotent, meaning that successive calls to ``CDB_CartodbfyTable()`` shall not produce any visible effect in the system.
- A call to the function shall modify/rewrite the table and produce a valid CartoDB table with the same name.
- A call to the function shall cause the registration of the table into the platform.
- It shall be idempotent, meaning that successive calls to the function shall not produce any visible effect in the system.
- If there's a column containing a geometry, it shall be used to generate ``the_geom`` and the ``the_geom_webmercator`` columns.
- Exporting and re-importing the same table in CartoDB shall produce equivalent tables, with the same features associated to the same ``cartodb_id``'s.
Note that there should be only one feature per row in the source table. If there's more than one, then which one is used for ``the_geom`` and ``the_geom_webmercator`` fields is not determined.
Note that there should be only one geometry per row in the source table. If there's more than one, then which one is used for ``the_geom`` and ``the_geom_webmercator`` fields is not determined.
Low-level requirements
======================
----------------------
- If the original table contains a valid (unique and not null) ``cartodb_id`` column, it shall be used
- If the original table contains a ``the_geom`` column or a ``the_geom_webmercator`` column in the expected projection (EPSG 4326 and EPSG 3857, respectively) they shall be used.
- If the original table contains a valid (integer, unique, non-zero and not null) ``cartodb_id`` column, it shall be used
- If the original table contains a ``the_geom`` column or a ``the_geom_webmercator`` geometric column in the expected projection (EPSG 4326 and EPSG 3857, respectively) they shall be used.
- A modification of a cartodbfy'ed table shall insert or update a row in ``CDB_TableMetadata``
- A cartodbfy'ed table shall have a ``btree`` index on ``cartodb_id``
- A cartodbfy'ed table shall have ``gist`` indices on ``the_geom`` and ``the_geom_webmercator``
- Cartodbfy shall deal with text columns for imports, regarding CartoDB columns
- Cartodbfy shall deal with text columns for imports, regarding CartoDB columns (``cartodb_id``, ``the_geom``, ``the_geom_webmercator``)

View File

@@ -1,199 +0,0 @@
\set VERBOSITY terse
-- Set user quota to infinite
SELECT CDB_SetUserQuotaInBytes(0);
cdb_setuserquotainbytes
-------------------------
0
(1 row)
-- Enable ddl triggers
SELECT cartodb.cdb_enable_ddl_hooks();
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
NOTICE: event trigger "cdb_on_drop_column" does not exist, skipping
NOTICE: event trigger "cdb_on_add_column" does not exist, skipping
cdb_enable_ddl_hooks
----------------------
(1 row)
create schema c;
SELECT CDB_SetUserQuotaInBytes('c', 0);
cdb_setuserquotainbytes
-------------------------
0
(1 row)
DROP USER IF EXISTS cartodb_postgresql_unpriv_user;
NOTICE: role "cartodb_postgresql_unpriv_user" does not exist, skipping
CREATE USER cartodb_postgresql_unpriv_user;
GRANT ALL ON SCHEMA c to cartodb_postgresql_unpriv_user;
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
--SELECT session_user, current_user;
----------------------
-- CREATE TABLE
----------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select 1 as i INTO c.t3;
NOTICE: trigger "track_updates" for table "c.t3" does not exist, skipping
NOTICE: trigger "update_the_geom_webmercator_trigger" for table "c.t3" does not exist, skipping
NOTICE: trigger "test_quota" for table "c.t3" does not exist, skipping
NOTICE: trigger "test_quota_per_row" for table "c.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
NOTICE: event trigger "cdb_on_drop_column" does not exist, skipping
NOTICE: event trigger "cdb_on_add_column" does not exist, skipping
NOTICE: cdb_invalidate_varnish(c.t3) called
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)) as age
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
tabname | age
---------+-----
c.t3 | 0
(1 row)
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
-- Table with cartodb_id field, see
-- http://github.com/CartoDB/cartodb-postgresql/issues/32
select 1 as cartodb_id INTO c.t4;
NOTICE: trigger "track_updates" for table "c.t4" does not exist, skipping
NOTICE: trigger "update_the_geom_webmercator_trigger" for table "c.t4" does not exist, skipping
NOTICE: trigger "test_quota" for table "c.t4" does not exist, skipping
NOTICE: trigger "test_quota_per_row" for table "c.t4" 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
NOTICE: event trigger "cdb_on_drop_column" does not exist, skipping
NOTICE: event trigger "cdb_on_add_column" does not exist, skipping
NOTICE: cdb_invalidate_varnish(c.t4) called
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)) as age
FROM CDB_TableMetadata WHERE tabname = 'c.t4'::regclass;
tabname | age
---------+-----
c.t4 | 0
(1 row)
----------------------------
-- ALTER TABLE RENAME COLUMN
----------------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
pg_sleep
----------
(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
NOTICE: event trigger "cdb_on_drop_column" does not exist, skipping
NOTICE: event trigger "cdb_on_add_column" does not exist, skipping
NOTICE: cdb_invalidate_varnish(c.t3) called
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
tabname | agecs
---------+-------
c.t3 | 0
(1 row)
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
pg_sleep
----------
(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
NOTICE: event trigger "cdb_on_drop_column" does not exist, skipping
NOTICE: event trigger "cdb_on_add_column" does not exist, skipping
NOTICE: cdb_invalidate_varnish(c.t3) called
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
tabname | agecs
---------+-------
c.t3 | 0
(1 row)
----------------------------
-- ALTER TABLE DROP COLUMN
----------------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
pg_sleep
----------
(1 row)
alter table c.t3 drop column the_geom_webmercator;
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
NOTICE: event trigger "cdb_on_drop_column" does not exist, skipping
NOTICE: event trigger "cdb_on_add_column" does not exist, skipping
NOTICE: cdb_invalidate_varnish(c.t3) called
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
tabname | agecs
---------+-------
c.t3 | 0
(1 row)
----------------------------
-- ALTER TABLE ADD COLUMN
----------------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
pg_sleep
----------
(1 row)
alter table c.t3 add column id2 int;
NOTICE: cdb_invalidate_varnish(c.t3) called
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
tabname | agecs
---------+-------
c.t3 | 0
(1 row)
----------------------------
-- DROP TABLE
----------------------------
RESET SESSION AUTHORIZATION;
drop schema c cascade;
NOTICE: drop cascades to 3 other objects
select count(*) from CDB_TableMetadata;
count
-------
0
(1 row)
DROP OWNED BY cartodb_postgresql_unpriv_user;
DROP ROLE cartodb_postgresql_unpriv_user;
DROP FUNCTION _CDB_UserQuotaInBytes();

View File

@@ -1,5 +1,4 @@
CREATE EXTENSION postgis;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION plpythonu;
CREATE EXTENSION cartodb;
CREATE FUNCTION public.cdb_invalidate_varnish(table_name text)

View File

@@ -0,0 +1,95 @@
-- Table to register analysis nodes from https://github.com/cartodb/camshaft
CREATE TABLE IF NOT EXISTS
cartodb.cdb_analysis_catalog (
-- md5 hex hash
node_id char(40) CONSTRAINT cdb_analysis_catalog_pkey PRIMARY KEY,
-- being json allows to do queries like analysis_def->>'type' = 'buffer'
analysis_def json NOT NULL,
-- can reference other nodes in this very same table, allowing recursive queries
input_nodes char(40) ARRAY NOT NULL DEFAULT '{}',
status TEXT NOT NULL DEFAULT 'pending',
CONSTRAINT valid_status CHECK (
status IN ( 'pending', 'waiting', 'running', 'canceled', 'failed', 'ready' )
),
created_at timestamp with time zone NOT NULL DEFAULT now(),
-- should be updated when some operation was performed in the node
-- and anything associated to it might have changed
updated_at timestamp with time zone DEFAULT NULL,
-- should register last time the node was used
used_at timestamp with time zone NOT NULL DEFAULT now(),
-- should register the number of times the node was used
hits NUMERIC DEFAULT 0,
-- should register what was the last node using current node
last_used_from char(40),
-- last job modifying the node
last_modified_by uuid,
-- store error message for failures
last_error_message text,
-- cached tables involved in the analysis
cache_tables regclass[] NOT NULL DEFAULT '{}',
-- useful for multi account deployments
username text
);
-- This can only be called from an SQL script executed by CREATE EXTENSION
DO LANGUAGE 'plpgsql' $$
BEGIN
PERFORM pg_catalog.pg_extension_config_dump('cartodb.cdb_analysis_catalog', '');
END
$$;
-- Migrations to add new columns from old versions.
-- IMPORTANT: Those columns will be added in order of creation. To be consistent
-- in column order, ensure that new columns are added at the end and in the same order.
DO $$
BEGIN
BEGIN
ALTER TABLE cartodb.cdb_analysis_catalog ADD COLUMN last_modified_by uuid;
EXCEPTION
WHEN duplicate_column THEN END;
END;
$$;
DO $$
BEGIN
BEGIN
ALTER TABLE cartodb.cdb_analysis_catalog ADD COLUMN last_error_message text;
EXCEPTION
WHEN duplicate_column THEN END;
END;
$$;
DO $$
BEGIN
BEGIN
ALTER TABLE cartodb.cdb_analysis_catalog ADD COLUMN cache_tables regclass[] NOT NULL DEFAULT '{}';
EXCEPTION
WHEN duplicate_column THEN END;
END;
$$;
DO $$
BEGIN
BEGIN
ALTER TABLE cartodb.cdb_analysis_catalog ADD COLUMN username text;
EXCEPTION
WHEN duplicate_column THEN END;
END;
$$;
-- We want the "username" column to be moved to the last position if it was on a position from other versions
-- see https://github.com/CartoDB/cartodb-postgresql/issues/276
DO LANGUAGE 'plpgsql' $$
DECLARE
column_index int;
BEGIN
SELECT ordinal_position FROM information_schema.columns WHERE table_name='cdb_analysis_catalog' AND table_schema='cartodb' AND column_name='username' INTO column_index;
IF column_index = 1 OR column_index = 10 THEN
ALTER TABLE cartodb.cdb_analysis_catalog ADD COLUMN username_final text;
UPDATE cartodb.cdb_analysis_catalog SET username_final = username;
ALTER TABLE cartodb.cdb_analysis_catalog DROP COLUMN username;
ALTER TABLE cartodb.cdb_analysis_catalog RENAME COLUMN username_final TO username;
END IF;
END;
$$;

View File

@@ -0,0 +1,62 @@
-- Read configuration parameter analysis_quota_factor, making it
-- accessible to regular users (which don't have access to cdb_conf)
CREATE OR REPLACE FUNCTION _CDB_GetConfAnalysisQuotaFactor()
RETURNS float8 AS
$$
BEGIN
RETURN CDB_Conf_GetConf('analysis_quota_factor')::text::float8;
END;
$$
LANGUAGE 'plpgsql' STABLE PARALLEL SAFE SECURITY DEFINER;
-- Get the factor (fraction of the quota) for Camshaft cached analysis tables
CREATE OR REPLACE FUNCTION _CDB_AnalysisQuotaFactor()
RETURNS float8 AS
$$
DECLARE
factor float8;
BEGIN
-- We use a floating point cdb_conf parameter
factor := _CDB_GetConfAnalysisQuotaFactor();
-- With a default value
IF factor IS NULL THEN
factor := 2;
END IF;
RETURN factor;
END;
$$
LANGUAGE 'plpgsql' STABLE PARALLEL SAFE;
-- This checks the space used up by Camshaft cached analysis tables.
-- An exception will be raised if the limits are exceeded.
-- The name of an analysis table is passed; this, in addition to the
-- db role that executes this function is used to determined which
-- analysis tables will be considered.
CREATE OR REPLACE FUNCTION CDB_CheckAnalysisQuota(table_name TEXT)
RETURNS void AS
$$
DECLARE
schema_name TEXT;
user_name TEXT;
nominal_quota int8;
cache_size float8;
BEGIN
-- We rely on the search_path to determine the user's schema and
-- check for all analysis tables in that schema.
-- An alternative would be to use cdb_analysis_catalog to
-- select analysis tables (cache_tables) from the same user, analysis or node.
-- For example:
-- SELECT unnest(cache_tables) FROM cdb_analysis_catalog
-- WHERE username IN (SELECT username FROM cdb_analysis_catalog
-- WHERE table_name::regclass = ANY (cache_tables));
-- At the moment we're not using the provided table_name.
SELECT current_schema() INTO schema_name;
EXECUTE FORMAT('SELECT %I._CDB_UserQuotaInBytes();', schema_name) INTO nominal_quota;
IF nominal_quota*_CDB_AnalysisQuotaFactor() < _CDB_AnalysisDataSize(schema_name) THEN
-- The limit is defined by a factor applied to the total space quota for the user
RAISE EXCEPTION 'Analysis cache space limits exceeded';
END IF;
END;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;

View File

@@ -0,0 +1,55 @@
-- Internal auxiliar functions to deal with [Camshaft](https://github.com/cartodb/camshaft) cached analysis tables.
-- This function returns TRUE if a given table name corresponds to a Camshaft cached analysis table
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_IsAnalysisTableName(table_name TEXT)
RETURNS BOOLEAN
AS $$
BEGIN
RETURN table_name SIMILAR TO '\Aanalysis_[0-9a-f]{10}_[0-9a-f]{40}\Z';
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- This function returns a relation of Camshaft cached analysis tables in the given schema.
-- If the schema name parameter is NULL, then tables from all schemas
-- that may contain user tables are returned.
-- For each table, the regclass, schema name and table name are returned.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_AnalysisTablesInSchema(schema_name text DEFAULT NULL)
RETURNS TABLE(table_regclass REGCLASS, schema_name TEXT, table_name TEXT)
AS $$
SELECT * FROM _CDB_UserTablesInSchema(schema_name) WHERE _CDB_IsAnalysisTableName(table_name);
$$ LANGUAGE 'sql' STABLE PARALLEL SAFE;
-- This function returns a relation user tables excluding analysis tables
-- If the schema name parameter is NULL, then tables from all schemas
-- that may contain user tables are returned.
-- For each table, the regclass, schema name and table name are returned.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_NonAnalysisTablesInSchema(schema_name text DEFAULT NULL)
RETURNS TABLE(table_regclass REGCLASS, schema_name TEXT, table_name TEXT)
AS $$
SELECT * FROM _CDB_UserTablesInSchema(schema_name) WHERE Not _CDB_IsAnalysisTableName(table_name);
$$ LANGUAGE 'sql' STABLE PARALLEL SAFE;
-- Total spaced used up by Camshaft cached analysis tables in the given schema.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_AnalysisDataSize(schema_name TEXT DEFAULT NULL)
RETURNS bigint AS
$$
DECLARE
total_size bigint;
BEGIN
WITH analysis_tables AS (
SELECT t.schema_name, t.table_name FROM _CDB_AnalysisTablesInSchema(schema_name) t
)
SELECT COALESCE(INT8(SUM(_CDB_total_relation_size(analysis_tables.schema_name, analysis_tables.table_name))))::int8
INTO total_size FROM analysis_tables;
IF total_size IS NOT NULL THEN
RETURN total_size;
ELSE
RETURN 0;
END IF;
END;
$$
LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;

View File

@@ -26,7 +26,7 @@ BEGIN
RAISE EXCEPTION 'Please set user quota before cartodbfying tables.';
END;
END;
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Drop cartodb triggers (might prevent changing columns)
CREATE OR REPLACE FUNCTION _CDB_drop_triggers(reloid REGCLASS)
@@ -49,7 +49,7 @@ BEGIN
sql := Format('DROP TRIGGER IF EXISTS test_quota_per_row ON %s', reloid::text);
EXECUTE sql;
END;
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Cartodb_id creation & validation or renaming if invalid
@@ -195,7 +195,7 @@ BEGIN
END;
END;
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Create all triggers
@@ -235,7 +235,7 @@ BEGIN
|| ''')';
EXECUTE sql;
END;
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- 8.b) Create all raster triggers
-- NOTE: drop/create has the side-effect of re-enabling disabled triggers
@@ -267,7 +267,7 @@ BEGIN
|| ''')';
EXECUTE sql;
END;
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
@@ -279,7 +279,7 @@ BEGIN
NEW.the_geom_webmercator := public.CDB_TransformToWebmercator(NEW.the_geom);
RETURN NEW;
END;
$$ LANGUAGE plpgsql VOLATILE;
$$ LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE;
--- 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
@@ -322,7 +322,7 @@ BEGIN
RETURN is_raster;
END;
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL STABLE PARALLEL UNSAFE;
@@ -347,7 +347,7 @@ $$ LANGUAGE PLPGSQL;
-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
--
-- CDB_CartodbfyTable(destschema TEXT, reloid REGCLASS)
--
--
-- Main function, calls the following functions, with a little
-- logic before the table re-write to avoid re-writing if the table
-- already has all the necessary columns in place.
@@ -398,7 +398,7 @@ geomcol := 'the_geom';
mercgeomcol := 'the_geom_webmercator';
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _CDB_Error(message TEXT, funcname TEXT DEFAULT '_CDB_Error')
@@ -409,7 +409,7 @@ BEGIN
RAISE EXCEPTION 'CDB(%): %', funcname, message;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _CDB_SQL(sql TEXT, funcname TEXT DEFAULT '_CDB_SQL')
@@ -425,7 +425,7 @@ BEGIN
RAISE EXCEPTION 'CDB(%:%:%): %', funcname, SQLSTATE, SQLERRM, sql;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
-- DEPRECATED: Use _CDB_Unique_Identifier since it's UTF8 Safe and length
@@ -444,7 +444,7 @@ BEGIN
RAISE EXCEPTION '_CDB_Unique_Relation_Name is DEPRECATED. Use _CDB_Unique_Identifier(prefix TEXT, relname TEXT, suffix TEXT, schema TEXT DEFAULT NULL)';
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL SAFE;
-- DEPRECATED: Use _CDB_Unique_Column_Identifier since it's UTF8 Safe and length
@@ -463,13 +463,14 @@ BEGIN
RAISE EXCEPTION '_CDB_Unique_Column_Name is DEPRECATED. Use _CDB_Unique_Column_Identifier(prefix TEXT, relname TEXT, suffix TEXT, reloid REGCLASS DEFAULT NULL)';
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL SAFE;
-- Find out if the table already has a usable primary key
-- If the table has both a usable key and usable geometry
-- we can no-op on the table copy and just ensure that the
-- we can no-op on the table copy and just ensure that the
-- indexes and triggers are in place
DROP FUNCTION IF EXISTS _CDB_Has_Usable_Primary_ID(reloid REGCLASS);
CREATE OR REPLACE FUNCTION _CDB_Has_Usable_Primary_ID(reloid REGCLASS)
RETURNS BOOLEAN
AS $$
@@ -489,116 +490,100 @@ BEGIN
-- Do we already have a properly named column?
SELECT a.attname, i.indisprimary, i.indisunique, a.attnotnull, a.atttypid
INTO rec
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = ANY(i.indkey)
WHERE c.oid = reloid
WHERE c.oid = reloid
AND NOT a.attisdropped
AND a.attname = const.pkey;
-- Found something named right...
IF FOUND THEN
-- And it's an integer column...
IF rec.atttypid IN (20,21,23) THEN
-- And it's a unique primary key! Done!
IF (rec.indisprimary OR rec.indisunique) AND rec.attnotnull THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', Format('found good ''%s''', const.pkey);
RETURN true;
-- Check and see if the column values are unique and not null,
-- if they are, we can use this column...
-- And it's a unique primary key! Done!
IF (rec.indisprimary OR rec.indisunique) AND rec.attnotnull THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', Format('found good ''%s''', const.pkey);
RETURN true;
-- Check and see if the column values are unique and not null,
-- if they are, we can use this column...
ELSE
-- Assume things are OK until proven otherwise...
useable_key := true;
BEGIN
sql := Format('ALTER TABLE %s ADD CONSTRAINT %s_pk PRIMARY KEY (%s)', reloid::text, const.pkey, const.pkey);
sql := sql || ', ' || Format('ADD CONSTRAINT %s_integer CHECK (%s::integer >=0);', const.pkey, const.pkey);
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', sql;
EXECUTE sql;
EXCEPTION
-- Failed unique check...
WHEN unique_violation THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', Format('column %s is not unique', const.pkey);
useable_key := false;
-- Failed not null check...
WHEN not_null_violation THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', Format('column %s contains nulls', const.pkey);
useable_key := false;
-- Failed integer check...
WHEN invalid_text_representation THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', Format('invalid input syntax for integer %s', const.pkey);
useable_key := false;
-- Other fatal error
WHEN others THEN
PERFORM _CDB_Error(sql, Format('_CDB_Has_Usable_Primary_ID: %s', SQLERRM));
END;
-- Clean up test constraint
IF useable_key THEN
PERFORM _CDB_SQL(Format('ALTER TABLE %s DROP CONSTRAINT %s_pk', reloid::text, const.pkey));
PERFORM _CDB_SQL(Format('ALTER TABLE %s DROP CONSTRAINT %s_integer', reloid::text, const.pkey));
-- Move non-valid column out of the way
ELSE
-- Assume things are OK until proven otherwise...
useable_key := true;
BEGIN
sql := Format('ALTER TABLE %s ADD CONSTRAINT %s_pk PRIMARY KEY (%s)', reloid::text, const.pkey, const.pkey);
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', sql;
EXECUTE sql;
EXCEPTION
-- Failed unique check...
WHEN unique_violation THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', Format('column %s is not unique', const.pkey);
useable_key := false;
-- Failed not null check...
WHEN not_null_violation THEN
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', Format('column %s contains nulls', const.pkey);
useable_key := false;
-- Other fatal error
WHEN others THEN
PERFORM _CDB_Error(sql, '_CDB_Has_Usable_Primary_ID');
END;
-- Clean up test constraint
IF useable_key THEN
PERFORM _CDB_SQL(Format('ALTER TABLE %s DROP CONSTRAINT %s_pk', reloid::text, const.pkey));
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %',
Format('found non-valid ''%s''', const.pkey);
-- Move non-unique column out of the way
ELSE
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %',
Format('found non-unique ''%s'', renaming it', const.pkey);
PERFORM _CDB_SQL(
Format('ALTER TABLE %s RENAME COLUMN %s TO %I',
reloid::text, rec.attname,
cartodb._CDB_Unique_Column_Identifier(NULL, const.pkey, NULL, reloid)),
'_CDB_Has_Usable_Primary_ID');
END IF;
return useable_key;
PERFORM _CDB_Error(sql, Format('_CDB_Has_Usable_Primary_ID: Error: invalid cartodb_id, %s', const.pkey));
END IF;
-- It's not an integer column, we have to rename it
ELSE
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %',
Format('found non-integer ''%s'', renaming it', const.pkey);
PERFORM _CDB_SQL(
Format('ALTER TABLE %s RENAME COLUMN %s TO %I',
reloid::text, rec.attname, cartodb._CDB_Unique_Column_Identifier(NULL, const.pkey, NULL, reloid)),
'_CDB_Has_Usable_Primary_ID');
RETURN useable_key;
END IF;
-- There's no column there named pkey
ELSE
-- Is there another suitable primary key already?
-- Is there another integer suitable primary key already?
SELECT a.attname
INTO rec
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = ANY(i.indkey)
WHERE c.oid = reloid AND NOT a.attisdropped
AND i.indisprimary AND i.indisunique AND a.attnotnull AND a.atttypid IN (20,21,23);
-- Yes! Ok, rename it.
IF FOUND THEN
PERFORM _CDB_SQL(Format('ALTER TABLE %s RENAME COLUMN %s TO %s', reloid::text, rec.attname, const.pkey),'_CDB_Has_Usable_Primary_ID');
RETURN true;
ELSE
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %',
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %',
Format('found no useful column for ''%s''', const.pkey);
END IF;
END IF;
RAISE DEBUG 'CDB(_CDB_Has_Usable_Primary_ID): %', 'function complete';
-- Didn't find re-usable key, so return FALSE
RETURN false;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION _CDB_Has_Usable_PK_Sequence(reloid REGCLASS)
@@ -618,7 +603,7 @@ BEGIN
RETURN has_sequence;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' STABLE PARALLEL SAFE;
-- Return a set of columns that can be candidates to be the_geom[webmercator]
-- with some extra information to analyze them.
@@ -647,7 +632,7 @@ BEGIN
AND postgis_typmod_srid(a.atttypmod) IN (4326, 3857, 0)
ORDER BY t.oid ASC;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' STABLE PARALLEL SAFE;
DO $$
BEGIN
@@ -674,12 +659,12 @@ DECLARE
rv RECORD;
const RECORD;
has_geom BOOLEAN := false;
has_mercgeom BOOLEAN := false;
has_geom_name TEXT;
has_mercgeom_name TEXT;
-- In case 'the_geom' is a text column
text_geom_column BOOLEAN := false;
text_geom_column_name TEXT := '';
@@ -700,12 +685,12 @@ BEGIN
FOR r1 IN
SELECT * FROM _cdb_geom_candidate_columns(reloid)
LOOP
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %', Format('checking column ''%s''', r1.attname);
-- Name collision: right name (the_geom, the_geomwebmercator?) but wrong type...
IF r1.typname != 'geometry' AND r1.attname = r1.desired_attname THEN
-- Maybe it's a geometry column hiding in a text column?
IF r1.typname IN ('text','varchar','char') THEN
@@ -725,14 +710,14 @@ BEGIN
END IF;
-- Nope, the text in the column can't be converted into geometry
-- so rename it out of the way
EXCEPTION
EXCEPTION
WHEN others THEN
IF SQLERRM = 'parse error - invalid geometry' THEN
text_geom_column := false;
str := cartodb._CDB_Unique_Column_Identifier(NULL, r1.attname, NULL, reloid);
sql := Format('ALTER TABLE %s RENAME COLUMN %s TO %I', reloid::text, r1.attname, str);
PERFORM _CDB_SQL(sql,'_CDB_Has_Usable_Geom');
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %',
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %',
Format('Text column %s is not convertible to geometry, renamed to %s', r1.attname, str);
ELSE
RAISE EXCEPTION 'CDB(_CDB_Has_Usable_Geom) UNEXPECTED ERROR';
@@ -744,7 +729,7 @@ BEGIN
str := cartodb._CDB_Unique_Column_Identifier(NULL, r1.attname, NULL, reloid);
sql := Format('ALTER TABLE %s RENAME COLUMN %s TO %I', reloid::text, r1.attname, str);
PERFORM _CDB_SQL(sql,'_CDB_Has_Usable_Geom');
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %',
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %',
Format('%s is the wrong type, renamed to %s', r1.attname, str);
END IF;
@@ -764,20 +749,20 @@ BEGIN
has_mercgeom := true;
has_mercgeom_name := r1.attname;
END IF;
-- If it's an unknown SRID, we need to know that too
ELSIF r1.srid = 0 THEN
-- Unknown SRID, we'll have to fill it in later
text_geom_column_srid := true;
END IF;
END IF;
END LOOP;
SELECT
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.
@@ -787,17 +772,17 @@ BEGIN
INTO rv;
RAISE DEBUG 'CDB(_CDB_Has_Usable_Geom): %', Format('returning %s', rv);
RETURN rv;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
-- 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
-- columns are in place already, it no-ops and just renames the table to
-- columns are in place already, it no-ops and just renames the table to
-- the destination if necessary.
CREATE OR REPLACE FUNCTION _CDB_Rewrite_Table(reloid REGCLASS, destschema TEXT DEFAULT NULL)
RETURNS BOOLEAN
@@ -806,6 +791,7 @@ DECLARE
relname TEXT;
relschema TEXT;
relseq TEXT;
destoid REGCLASS;
destname TEXT;
@@ -825,10 +811,10 @@ DECLARE
str TEXT;
table_srid INTEGER;
geom_srid INTEGER;
has_usable_primary_key BOOLEAN;
has_usable_pk_sequence BOOLEAN;
BEGIN
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): %', 'entered function';
@@ -839,7 +825,7 @@ BEGIN
-- Save the raw schema/table names for later
SELECT n.nspname, c.relname, c.relname
INTO STRICT relschema, relname, destname
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.oid = reloid;
-- Default the destination to current schema if unspecified
@@ -868,7 +854,7 @@ BEGIN
-- transformation of the table, we can just ensure proper
-- indexes are in place and apply a rename
SELECT *
FROM _CDB_Has_Usable_Geom(reloid)
FROM _CDB_Has_Usable_Geom(reloid)
INTO STRICT gc;
-- If geom is the wrong name, just rename it.
@@ -890,7 +876,7 @@ BEGIN
RAISE DEBUG 'CDB(_CDB_Rewrite_Table): has_usable_geoms %', gc.has_usable_geoms;
-- We can only avoid a rewrite if both the key and
-- 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
@@ -913,6 +899,21 @@ BEGIN
-- We must rewrite, so here we go...
-- Our desired PK sequence name
-- We are going to drop the source table when we're done anyways
-- but it's possible the source PK sequence is living in a name we would like to use
-- so we check to see if that's the case, and rename it out of the way
IF has_usable_primary_key AND has_usable_pk_sequence THEN
-- See if the existing sequence is squatting on our preferred name
destseq := Format('%s_%s_seq', relname, const.pkey);
SELECT pg_catalog.pg_get_serial_sequence(Format('%I.%I', relschema, relname), const.pkey)
INTO relseq;
-- If it's the name we want, then rename it
IF relseq IS NOT NULL AND relseq = Format('%I.%I', destschema, destseq) THEN
PERFORM _CDB_SQL(Format('ALTER SEQUENCE %s RENAME TO %I', relseq, Format('tmp_%s', destseq)), '_CDB_Rewrite_Table');
END IF;
END IF;
-- Put the primary key sequence in the right schema
-- If the new table is not moving, better ensure the sequence name
@@ -934,7 +935,7 @@ BEGIN
-- Add cartodb ID!
IF has_usable_primary_key THEN
sql := sql || const.pkey;
sql := sql || const.pkey || '::integer ';
ELSE
sql := sql || 'nextval(''' || destseq || ''') AS ' || const.pkey;
END IF;
@@ -946,16 +947,16 @@ BEGIN
-- Arg, this "geometry" column is actually text!!
-- OK, we tested back in our geometry column research that it could
-- be safely cast to geometry, so let's do that.
-- be safely cast to geometry, so let's do that.
IF gc.text_geom_column THEN
WITH t AS (
SELECT
SELECT
a.attname,
CASE WHEN NOT gc.text_geom_column_srid THEN 'ST_SetSRID(' ELSE '' END AS missing_srid_start,
CASE WHEN NOT gc.text_geom_column_srid THEN ',4326)' ELSE '' END AS missing_srid_end
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid
WHERE c.oid = reloid
AND t.typname IN ('text','varchar','char')
@@ -969,7 +970,7 @@ BEGIN
|| t.missing_srid_start || t.attname || '::geometry' || t.missing_srid_end
|| ',4326)::Geometry(GEOMETRY,4326) AS '
|| const.geomcol
|| ', cartodb.CDB_TransformToWebmercator('
|| ', cartodb.CDB_TransformToWebmercator('
|| t.missing_srid_start || t.attname || '::geometry' || t.missing_srid_end
|| ')::Geometry(GEOMETRY,3857) AS '
|| const.mercgeomcol,
@@ -982,19 +983,19 @@ BEGIN
-- better be found.
RAISE EXCEPTION 'CDB(_CDB_Rewrite_Table): Text column % is missing!', gc.text_geom_column_name;
ELSE
sql := sql || geom_transform_sql;
sql := sql || geom_transform_sql;
END IF;
-- There is at least one true geometry column in here, we'll
-- reproject that into the projections we need.
-- reproject that into the projections we need.
ELSE
-- Find the column we are going to be working with (the first
-- column with type "geometry")
SELECT a.attname
INTO rec
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid
WHERE c.oid = reloid
AND t.typname = 'geometry'
@@ -1004,16 +1005,16 @@ BEGIN
LIMIT 1;
-- The SRID could be undeclared at the table level, but still
-- exist in the geometries themselves. We first find our geometry
-- exist in the geometries themselves. We first find our geometry
-- column and read the first SRID off it it, if there is a row
-- to read.
IF FOUND THEN
EXECUTE Format('SELECT ST_SRID(%s) AS srid FROM %s LIMIT 1', rec.attname, reloid::text)
EXECUTE Format('SELECT ST_SRID(%s) AS srid FROM %s LIMIT 1', rec.attname, reloid::text)
INTO geom_srid;
ELSE
geom_srid := 0;
END IF;
-- The geometry columns weren't in the right projection,
-- so we need to find the first decent geometry column
-- in the table and wrap it in two transforms, one to 4326
@@ -1021,13 +1022,13 @@ BEGIN
-- ignore it when we build the list of other columns to
-- add to the output table
WITH t AS (
SELECT
a.attname,
postgis_typmod_type(a.atttypmod) AS geomtype,
SELECT
a.attname,
postgis_typmod_type(a.atttypmod) AS geomtype,
CASE WHEN postgis_typmod_srid(a.atttypmod) = 0 AND srid.srid = 0 THEN 'ST_SetSRID(' ELSE '' END AS missing_srid_start,
CASE WHEN postgis_typmod_srid(a.atttypmod) = 0 AND srid.srid = 0 THEN ',4326)' ELSE '' END AS missing_srid_end
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid,
( SELECT geom_srid AS srid ) AS srid
WHERE c.oid = reloid
@@ -1037,22 +1038,22 @@ BEGIN
ORDER BY a.attnum
LIMIT 1
)
SELECT ', ST_Transform('
SELECT ', ST_Transform('
|| t.missing_srid_start || t.attname || t.missing_srid_end
|| ',4326)::Geometry(GEOMETRY,4326) AS '
|| const.geomcol
|| ', cartodb.CDB_TransformToWebmercator('
|| ', cartodb.CDB_TransformToWebmercator('
|| t.missing_srid_start || t.attname || t.missing_srid_end
|| ')::Geometry(GEOMETRY,3857) AS '
|| const.mercgeomcol,
t.attname
INTO geom_transform_sql, geom_column_source
FROM t;
IF NOT FOUND THEN
-- If there are no geometry columns, we continue making a
-- If there are no geometry columns, we continue making a
-- non-spatial table. This is important for folks who want
-- their tables to invalidate the SQL API
-- their tables to invalidate the SQL API
-- cache on update/insert/delete.
geom_column_source := '';
sql := sql || ',NULL::geometry(Geometry,4326) AS ' || const.geomcol;
@@ -1072,8 +1073,8 @@ BEGIN
',' || array_to_string(array_agg(Format('%I',a.attname)),',') AS column_name_sql,
Count(*) AS count
INTO rec
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_type t ON a.atttypid = t.oid
WHERE c.oid = reloid
AND a.attnum > 0
@@ -1096,7 +1097,7 @@ BEGIN
-- Run it!
PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table');
-- 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
@@ -1118,11 +1119,11 @@ BEGIN
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);
PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table');
-- If the table is being created by a SECURITY DEFINER function
-- make sure the user is set back to the user who is connected
IF current_user != session_user THEN
@@ -1131,7 +1132,7 @@ BEGIN
sql := Format('ALTER SEQUENCE IF EXISTS %s OWNER TO %s', destseq, session_user);
PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table');
END IF;
-- If we used a temporary destination table
-- we can now rename it into place
IF destschema = relschema THEN
@@ -1142,7 +1143,7 @@ BEGIN
RETURN true;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
-- Assumes the table already has the right metadata columns
@@ -1170,15 +1171,15 @@ BEGIN
FROM pg_class c
WHERE c.oid = reloid;
-- Is there already a primary key on this table for
-- Is there already a primary key on this table for
-- a column other than our chosen primary key?
SELECT ci.relname AS pkey
INTO rec
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
LEFT JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = ANY(i.indkey)
JOIN pg_class ci ON i.indexrelid = ci.oid
WHERE c.oid = reloid
WHERE c.oid = reloid
AND NOT a.attisdropped
AND a.attname != const.pkey
AND i.indisprimary;
@@ -1195,40 +1196,40 @@ BEGIN
-- Is the default primary key flagged as primary?
SELECT a.attname
INTO rec
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = ANY(i.indkey)
JOIN pg_class ci ON ci.oid = i.indexrelid
WHERE attnum > 0
WHERE attnum > 0
AND c.oid = reloid
AND a.attname = const.pkey
AND i.indisprimary
AND i.indisunique
AND NOT attisdropped;
-- No primary key? Add one.
IF NOT FOUND THEN
sql := Format('ALTER TABLE %s ADD PRIMARY KEY (%s)', reloid::text, const.pkey);
PERFORM _CDB_SQL(sql, '_CDB_Add_Indexes');
END IF;
-- Add geometry indexes to all "special geometry columns" that
-- Add geometry indexes to all "special geometry columns" that
-- don't have one (either have no index at all, or have a non-GIST index)
FOR rec IN
FOR rec IN
SELECT a.attname, n.nspname
FROM pg_class c
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_attribute a ON a.attrelid = c.oid AND attnum > 0
JOIN pg_attribute a ON a.attrelid = c.oid AND attnum > 0
LEFT JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = ANY(i.indkey)
WHERE NOT attisdropped
AND a.attname IN (const.geomcol, const.mercgeomcol)
AND c.oid = reloid
AND i.indexrelid IS NULL
UNION
UNION
SELECT a.attname, n.nspname
FROM pg_class c
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_attribute a ON a.attrelid = c.oid AND attnum > 0
JOIN pg_attribute a ON a.attrelid = c.oid AND attnum > 0
JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = ANY(i.indkey)
JOIN pg_class ci ON ci.oid = i.indexrelid
JOIN pg_am am ON ci.relam = am.oid
@@ -1240,18 +1241,18 @@ BEGIN
sql := Format('CREATE INDEX ON %s USING GIST (%s)', reloid::text, rec.attname);
PERFORM _CDB_SQL(sql, '_CDB_Add_Indexes');
END LOOP;
RETURN true;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
DROP FUNCTION IF EXISTS CDB_CartodbfyTable(destschema TEXT, reloid REGCLASS);
CREATE OR REPLACE FUNCTION CDB_CartodbfyTable(destschema TEXT, reloid REGCLASS)
RETURNS REGCLASS
AS $$
DECLARE
is_raster BOOLEAN;
relname TEXT;
relschema TEXT;
@@ -1260,13 +1261,13 @@ DECLARE
destname TEXT;
rec RECORD;
BEGIN
-- Save the raw schema/table names for later
SELECT n.nspname, c.relname, c.relname
INTO STRICT relschema, relname, destname
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.oid = reloid;
PERFORM cartodb._CDB_check_prerequisites(destschema, reloid);
@@ -1274,7 +1275,7 @@ BEGIN
-- Check destination schema exists
-- Throws an exception of there is no matching schema
IF destschema IS NOT NULL THEN
SELECT n.nspname
INTO rec FROM pg_namespace n WHERE n.nspname = destschema;
IF NOT FOUND THEN
@@ -1297,7 +1298,7 @@ BEGIN
PERFORM cartodb._CDB_create_raster_triggers(destschema, reloid);
ELSE
-- Rewrite (or rename) the table to the new location
PERFORM _CDB_Rewrite_Table(reloid, destschema);
@@ -1306,7 +1307,7 @@ BEGIN
-- Add indexes to the destination table, as necessary
PERFORM _CDB_Add_Indexes(destoid);
-- Add triggers to the destination table, as necessary
PERFORM _CDB_create_triggers(destschema, destoid);
@@ -1314,4 +1315,4 @@ BEGIN
RETURN (destschema || '.' || destname)::regclass;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;

View File

@@ -2,15 +2,14 @@
CREATE OR REPLACE FUNCTION CDB_ColumnNames(REGCLASS)
RETURNS SETOF information_schema.sql_identifier
AS $$
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;
SELECT
a.attname::information_schema.sql_identifier column_name
FROM pg_class c
LEFT JOIN pg_attribute a ON a.attrelid = c.oid
WHERE c.oid = $1::oid
AND a.attstattarget < 0 -- exclude system columns
ORDER BY a.attnum;
$$ LANGUAGE SQL STABLE PARALLEL SAFE;
-- This is to migrate from pre-0.2.0 version
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36

View File

@@ -2,16 +2,14 @@
CREATE OR REPLACE FUNCTION CDB_ColumnType(REGCLASS, TEXT)
RETURNS information_schema.character_data
AS $$
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;
SELECT
format_type(a.atttypid, NULL)::information_schema.character_data data_type
FROM pg_class c
LEFT JOIN pg_attribute a ON a.attrelid = c.oid
WHERE c.oid = $1::oid
AND a.attname = $2
AND a.attstattarget < 0; -- exclude system columns
$$ LANGUAGE SQL STABLE PARALLEL SAFE;
-- This is to migrate from pre-0.2.0 version
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36

View File

@@ -26,7 +26,7 @@ BEGIN
PERFORM cartodb.CDB_Conf_RemoveConf(key);
EXECUTE 'INSERT INTO cartodb.CDB_CONF (KEY, VALUE) VALUES ($1, $2);' USING key, value;
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Conf_RemoveConf(key text)
@@ -34,7 +34,7 @@ FUNCTION cartodb.CDB_Conf_RemoveConf(key text)
BEGIN
EXECUTE 'DELETE FROM cartodb.CDB_CONF WHERE KEY = $1;' USING key;
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Conf_GetConf(key text)
@@ -45,4 +45,4 @@ BEGIN
EXECUTE 'SELECT VALUE FROM cartodb.CDB_CONF WHERE KEY = $1;' INTO value USING key;
RETURN value;
END
$$ LANGUAGE PLPGSQL STABLE;
$$ LANGUAGE PLPGSQL STABLE PARALLEL SAFE;

View File

@@ -1,214 +0,0 @@
-- Table creation
-- {
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_create_table ()
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE
event_info RECORD;
rel RECORD;
newtable REGCLASS;
BEGIN
event_info := schema_triggers.get_relation_create_eventinfo();
-- We're only interested in real relations
IF (event_info.new).relkind != 'r' THEN RETURN; END IF;
SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Relation % of kind % created in table % namespace % (oid %)',
event_info.relation, rel.relkind, rel.relname, rel.nspname, rel.relnamespace;
-- We don't want to react to alters triggered by superuser,
IF current_setting('is_superuser') = 'on' THEN
RAISE DEBUG 'no ddl trigger for superuser';
RETURN;
END IF;
PERFORM cartodb.cdb_disable_ddl_hooks();
-- CDB_CartodbfyTable must not create tables, or infinite loop will happen
newtable := cartodb.CDB_CartodbfyTable(rel.nspname, event_info.relation);
PERFORM cartodb.cdb_enable_ddl_hooks();
RAISE DEBUG 'Inserting into cartodb.CDB_TableMetadata';
-- Add entry to CDB_TableMetadata (should CartodbfyTable do this?)
INSERT INTO cartodb.CDB_TableMetadata(tabname, updated_at)
VALUES (newtable, now());
END; $$;
-- }
-- Table drop
-- {
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_drop_table ()
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE
event_info RECORD;
BEGIN
event_info := schema_triggers.get_relation_drop_eventinfo();
-- We're only interested in real relations
IF (event_info.old).relkind != 'r' THEN RETURN; END IF;
RAISE DEBUG 'Relation % of kind % dropped from namespace oid %',
event_info.old_relation_oid, (event_info.old).relkind, (event_info.old).relnamespace;
-- delete record from CDB_TableMetadata (should invalidate varnish)
DELETE FROM cartodb.CDB_TableMetadata WHERE tabname = event_info.old_relation_oid;
END; $$;
-- }
-- Column alter
-- {
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_alter_column ()
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE
event_info RECORD;
rel RECORD;
newtable REGCLASS;
BEGIN
event_info := schema_triggers.get_column_alter_eventinfo();
SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Column % altered by % (superuser? %) in relation % of kind %',
(event_info.old).attname, current_user, current_setting('is_superuser'), rel.relname, rel.relkind;
-- We're only interested in real relations
IF rel.relkind != 'r' THEN RETURN; END IF;
-- We don't want to react to alters triggered by superuser,
IF current_setting('is_superuser') = 'on' THEN
RAISE DEBUG 'no ddl trigger for superuser';
RETURN;
END IF;
PERFORM cartodb.cdb_disable_ddl_hooks();
newtable := cartodb.CDB_CartodbfyTable(rel.nspname, event_info.relation);
PERFORM cartodb.cdb_enable_ddl_hooks();
-- update CDB_TableMetadata.updated_at (should invalidate varnish)
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW(), tabname = newtable
WHERE tabname = event_info.relation;
END; $$;
-- }
-- Column drop
-- {
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_drop_column ()
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE
event_info RECORD;
rel RECORD;
newtable REGCLASS;
BEGIN
event_info := schema_triggers.get_column_drop_eventinfo();
SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Column % drop by % (superuser? %) in relation % of kind %',
(event_info.old).attname, current_user, current_setting('is_superuser'), rel.relname, rel.relkind;
-- We're only interested in real relations
IF rel.relkind != 'r' THEN RETURN; END IF;
-- We don't want to react to drops triggered by superuser,
IF current_setting('is_superuser') = 'on' THEN
RAISE DEBUG 'no ddl trigger for superuser';
RETURN;
END IF;
PERFORM cartodb.cdb_disable_ddl_hooks();
newtable := cartodb.CDB_CartodbfyTable(rel.nspname, event_info.relation);
PERFORM cartodb.cdb_enable_ddl_hooks();
-- update CDB_TableMetadata.updated_at (should invalidate varnish)
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW(), tabname = newtable
WHERE tabname = event_info.relation;
END; $$;
-- }
-- Column add
-- {
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_add_column ()
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE
event_info RECORD;
rel RECORD;
BEGIN
event_info := schema_triggers.get_column_add_eventinfo();
SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Column % added by % (superuser? %) in relation % of kind %',
(event_info.new).attname, current_user, current_setting('is_superuser'), rel.relname, rel.relkind;
-- We're only interested in real relations
IF rel.relkind != 'r' THEN RETURN; END IF;
-- We don't want to react to drops triggered by superuser,
IF current_setting('is_superuser') = 'on' THEN
RAISE DEBUG 'no ddl trigger for superuser';
RETURN;
END IF;
-- update CDB_TableMetadata.updated_at (should invalidate varnish)
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW()
WHERE tabname = event_info.relation;
END; $$;
-- }
CREATE OR REPLACE FUNCTION cartodb.cdb_disable_ddl_hooks() returns void AS $$
DROP EVENT TRIGGER IF EXISTS cdb_on_relation_create;
DROP EVENT TRIGGER IF EXISTS cdb_on_relation_drop;
DROP EVENT TRIGGER IF EXISTS cdb_on_alter_column;
DROP EVENT TRIGGER IF EXISTS cdb_on_drop_column;
DROP EVENT TRIGGER IF EXISTS cdb_on_add_column;
$$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION cartodb.cdb_enable_ddl_hooks() returns void AS $$
SELECT cartodb.cdb_disable_ddl_hooks();
CREATE EVENT TRIGGER cdb_on_relation_create
ON "relation_create" EXECUTE PROCEDURE cartodb.cdb_handle_create_table();
CREATE EVENT TRIGGER cdb_on_relation_drop
ON "relation_drop" EXECUTE PROCEDURE cartodb.cdb_handle_drop_table();
CREATE EVENT TRIGGER cdb_on_alter_column
ON "column_alter" EXECUTE PROCEDURE cartodb.cdb_handle_alter_column();
CREATE EVENT TRIGGER cdb_on_drop_column
ON "column_drop" EXECUTE PROCEDURE cartodb.cdb_handle_drop_column();
CREATE EVENT TRIGGER cdb_on_add_column
ON "column_add" EXECUTE PROCEDURE cartodb.cdb_handle_add_column();
$$ LANGUAGE sql;
-- Do not enable hooks by default
--SELECT cartodb.cdb_enable_ddl_hooks();

View File

@@ -12,7 +12,7 @@ BEGIN
RETURN output;
END;
$$
LANGUAGE 'plpgsql' STABLE STRICT;
LANGUAGE 'plpgsql' IMMUTABLE STRICT PARALLEL UNSAFE;
-- Convert timestamp with time zone to double precision
--
@@ -28,4 +28,4 @@ BEGIN
RETURN output;
END;
$$
LANGUAGE 'plpgsql' STABLE STRICT;
LANGUAGE 'plpgsql' IMMUTABLE STRICT PARALLEL UNSAFE;

View File

@@ -50,4 +50,4 @@ BEGIN
END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
LANGUAGE 'plpgsql' STABLE STRICT PARALLEL SAFE;

View File

@@ -65,7 +65,7 @@ BEGIN
RETURN signature;
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql IMMUTABLE STRICT PARALLEL SAFE;
-- Classify data into AJUSFL
@@ -119,4 +119,4 @@ BEGIN
RETURN type;
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql IMMUTABLE STRICT PARALLEL SAFE;

View File

@@ -43,4 +43,4 @@ BEGIN
RETURN passes;
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql IMMUTABLE PARALLEL SAFE;

View File

@@ -1,8 +1,8 @@
--
-- Calculate the equal interval bins for a given column
--
-- @param in_array A numeric array of numbers to determine the best
-- to determine the bin boundary
-- @param in_array An array of numbers to determine the best
-- bin boundary
--
-- @param breaks The number of bins you want to find.
--
@@ -11,27 +11,14 @@
--
--
CREATE OR REPLACE FUNCTION CDB_EqualIntervalBins ( in_array NUMERIC[], breaks INT ) RETURNS NUMERIC[] as $$
DECLARE
diff numeric;
min_val numeric;
max_val numeric;
tmp_val numeric;
i INT := 1;
reply numeric[];
BEGIN
SELECT min(e), max(e) INTO min_val, max_val FROM ( SELECT unnest(in_array) e ) x WHERE e IS NOT NULL;
diff = (max_val - min_val) / breaks::numeric;
LOOP
IF i < breaks THEN
tmp_val = min_val + i::numeric * diff;
reply = array_append(reply, tmp_val);
i := i+1;
ELSE
reply = array_append(reply, max_val);
EXIT;
END IF;
END LOOP;
RETURN reply;
END;
$$ language plpgsql IMMUTABLE;
CREATE OR REPLACE FUNCTION CDB_EqualIntervalBins ( in_array anyarray, breaks INT ) RETURNS anyarray as $$
WITH stats AS (
SELECT min(e), (max(e)-min(e))/breaks AS del
FROM (SELECT unnest(in_array) e) AS p)
SELECT array_agg(bins)
FROM (
SELECT min + generate_series(1,breaks)*del AS bins
FROM stats) q;
$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
DROP FUNCTION IF EXISTS CDB_EqualIntervalBins( numeric[], integer);

View File

@@ -0,0 +1,31 @@
-- Internal function to generate stats for a table if they don't exist
CREATE OR REPLACE FUNCTION _CDB_GenerateStats(reloid REGCLASS)
RETURNS VOID
AS $$
DECLARE
has_stats BOOLEAN;
BEGIN
SELECT EXISTS (
SELECT * FROM pg_catalog.pg_statistic WHERE starelid = reloid
) INTO has_stats;
IF NOT has_stats THEN
EXECUTE Format('ANALYZE %s;', reloid);
END IF;
END
$$ LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL RESTRICTED SECURITY DEFINER;
-- Return a row count estimate of the result of a query using statistics
CREATE OR REPLACE FUNCTION CDB_EstimateRowCount(query text)
RETURNS Numeric
AS $$
DECLARE
plan JSON;
BEGIN
-- Make sure statistics exist for all the tables of the query
PERFORM _CDB_GenerateStats(tabname) FROM unnest(CDB_QueryTablesText(query)) AS tabname;
-- Use the query planner to obtain an estimate of the number of result rows
EXECUTE 'EXPLAIN (FORMAT JSON) ' || query INTO STRICT plan;
RETURN plan->0->'Plan'->'Plan Rows';
END
$$ LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL RESTRICTED;

View File

@@ -10,11 +10,11 @@ BEGIN
sql := 'ALTER EXTENSION cartodb UPDATE TO ''' || ver || '''';
EXECUTE sql;
END;
$$ language 'plpgsql' VOLATILE;
$$ language 'plpgsql' VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION cartodb.schema_exists(schema_name text)
RETURNS boolean AS
$$
SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = schema_name::text);
$$
language sql VOLATILE;
language sql STABLE PARALLEL SAFE;

View File

@@ -0,0 +1,199 @@
---------------------------
-- FDW MANAGEMENT FUNCTIONS
--
-- All the FDW settings are read from the `cdb_conf.fdws` entry json file.
---------------------------
CREATE OR REPLACE FUNCTION cartodb._CDB_Setup_FDW(fdw_name text, config json)
RETURNS void
AS $$
DECLARE
row record;
option record;
org_role text;
BEGIN
-- This function tries to be as idempotent as possible, by not creating anything more than once
-- (not even using IF NOT EXIST to avoid throwing warnings)
IF NOT EXISTS ( SELECT * FROM pg_extension WHERE extname = 'postgres_fdw') THEN
CREATE EXTENSION postgres_fdw;
END IF;
-- Create FDW first if it does not exist
IF NOT EXISTS ( SELECT * FROM pg_foreign_server WHERE srvname = fdw_name)
THEN
EXECUTE FORMAT('CREATE SERVER %I FOREIGN DATA WRAPPER postgres_fdw', fdw_name);
END IF;
-- Set FDW settings
FOR row IN SELECT p.key, p.value from lateral json_each_text(config->'server') p
LOOP
IF NOT EXISTS (WITH a AS (select split_part(unnest(srvoptions), '=', 1) as options from pg_foreign_server where srvname=fdw_name) SELECT * from a where options = row.key)
THEN
EXECUTE FORMAT('ALTER SERVER %I OPTIONS (ADD %I %L)', fdw_name, row.key, row.value);
ELSE
EXECUTE FORMAT('ALTER SERVER %I OPTIONS (SET %I %L)', fdw_name, row.key, row.value);
END IF;
END LOOP;
-- Create user mappings
FOR row IN SELECT p.key, p.value from lateral json_each(config->'users') p LOOP
-- Check if entry on pg_user_mappings exists
IF NOT EXISTS ( SELECT * FROM pg_user_mappings WHERE srvname = fdw_name AND usename = row.key ) THEN
EXECUTE FORMAT ('CREATE USER MAPPING FOR %I SERVER %I', row.key, fdw_name);
END IF;
-- Update user mapping settings
FOR option IN SELECT o.key, o.value from lateral json_each_text(row.value) o LOOP
IF NOT EXISTS (WITH a AS (select split_part(unnest(umoptions), '=', 1) as options from pg_user_mappings WHERE srvname = fdw_name AND usename = row.key) SELECT * from a where options = option.key) THEN
EXECUTE FORMAT('ALTER USER MAPPING FOR %I SERVER %I OPTIONS (ADD %I %L)', row.key, fdw_name, option.key, option.value);
ELSE
EXECUTE FORMAT('ALTER USER MAPPING FOR %I SERVER %I OPTIONS (SET %I %L)', row.key, fdw_name, option.key, option.value);
END IF;
END LOOP;
END LOOP;
-- Create schema if it does not exist.
IF NOT EXISTS ( SELECT * from pg_namespace WHERE nspname=fdw_name) THEN
EXECUTE FORMAT ('CREATE SCHEMA %I', fdw_name);
END IF;
-- Give the organization role usage permisions over the schema
SELECT cartodb.CDB_Organization_Member_Group_Role_Member_Name() INTO org_role;
EXECUTE FORMAT ('GRANT USAGE ON SCHEMA %I TO %I', fdw_name, org_role);
-- Bring here the remote cdb_tablemetadata
IF NOT EXISTS ( SELECT * FROM PG_CLASS WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname=fdw_name) and relname='cdb_tablemetadata') THEN
EXECUTE FORMAT ('CREATE FOREIGN TABLE %I.cdb_tablemetadata (tabname text, updated_at timestamp with time zone) SERVER %I OPTIONS (table_name ''cdb_tablemetadata_text'', schema_name ''public'', updatable ''false'')', fdw_name, fdw_name);
END IF;
EXECUTE FORMAT ('GRANT SELECT ON %I.cdb_tablemetadata TO %I', fdw_name, org_role);
END
$$
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION cartodb._CDB_Setup_FDWS()
RETURNS VOID AS
$$
DECLARE
row record;
BEGIN
FOR row IN SELECT p.key, p.value from lateral json_each(cartodb.CDB_Conf_GetConf('fdws')) p LOOP
EXECUTE 'SELECT cartodb._CDB_Setup_FDW($1, $2)' USING row.key, row.value;
END LOOP;
END
$$
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION cartodb._CDB_Setup_FDW(fdw_name text)
RETURNS void AS
$BODY$
DECLARE
config json;
BEGIN
SELECT p.value FROM LATERAL json_each(cartodb.CDB_Conf_GetConf('fdws')) p WHERE p.key = fdw_name INTO config;
EXECUTE 'SELECT cartodb._CDB_Setup_FDW($1, $2)' USING fdw_name, config;
END
$BODY$
LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION cartodb.CDB_Add_Remote_Table(source text, table_name text)
RETURNS void AS
$$
BEGIN
PERFORM cartodb._CDB_Setup_FDW(source);
EXECUTE FORMAT ('IMPORT FOREIGN SCHEMA %I LIMIT TO (%I) FROM SERVER %I INTO %I;', source, table_name, source, source);
--- Grant SELECT to publicuser
EXECUTE FORMAT ('GRANT SELECT ON %I.%I TO publicuser;', source, table_name);
END
$$
LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION cartodb.CDB_Get_Foreign_Updated_At(foreign_table regclass)
RETURNS timestamp with time zone AS
$$
DECLARE
remote_table_name text;
fdw_schema_name text;
time timestamp with time zone;
BEGIN
-- This will turn a local foreign table (referenced as regclass) to its fully qualified text remote table reference.
WITH a AS (SELECT ftoptions FROM pg_foreign_table WHERE ftrelid=foreign_table LIMIT 1),
b as (SELECT (pg_options_to_table(ftoptions)).* FROM a)
SELECT FORMAT('%I.%I', (SELECT option_value FROM b WHERE option_name='schema_name'), (SELECT option_value FROM b WHERE option_name='table_name'))
INTO remote_table_name;
-- We assume that the remote cdb_tablemetadata is called cdb_tablemetadata and is on the same schema as the queried table.
SELECT nspname FROM pg_class c, pg_namespace n WHERE c.oid=foreign_table AND c.relnamespace = n.oid INTO fdw_schema_name;
EXECUTE FORMAT('SELECT updated_at FROM %I.cdb_tablemetadata WHERE tabname=%L ORDER BY updated_at DESC LIMIT 1', fdw_schema_name, remote_table_name) INTO time;
RETURN time;
END
$$
LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION cartodb._cdb_dbname_of_foreign_table(reloid oid)
RETURNS TEXT AS $$
SELECT option_value FROM pg_options_to_table((
SELECT fs.srvoptions
FROM pg_foreign_table ft
LEFT JOIN pg_foreign_server fs ON ft.ftserver = fs.oid
WHERE ft.ftrelid = reloid
)) WHERE option_name='dbname';
$$ LANGUAGE SQL VOLATILE PARALLEL UNSAFE;
-- Return a set of (dbname, schema_name, table_name, updated_at)
-- It is aware of foreign tables
-- It assumes the local (schema_name, table_name) map to the remote ones with the same name
-- Note: dbname is never quoted whereas schema and table names are when needed.
CREATE OR REPLACE FUNCTION cartodb.CDB_QueryTables_Updated_At(query text)
RETURNS TABLE(dbname text, schema_name text, table_name text, updated_at timestamptz)
AS $$
WITH query_tables AS (
SELECT unnest(CDB_QueryTablesText(query)) schema_table_name
), query_tables_oid AS (
SELECT schema_table_name, schema_table_name::regclass::oid AS reloid
FROM query_tables
),
fqtn AS (
SELECT
(CASE WHEN c.relkind = 'f' THEN cartodb._cdb_dbname_of_foreign_table(query_tables_oid.reloid)
ELSE current_database()
END)::text AS dbname,
quote_ident(n.nspname::text) schema_name,
quote_ident(c.relname::text) table_name,
c.relkind,
query_tables_oid.reloid
FROM query_tables_oid, pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
WHERE c.oid = query_tables_oid.reloid
)
SELECT fqtn.dbname, fqtn.schema_name, fqtn.table_name,
(CASE WHEN relkind = 'f' THEN cartodb.CDB_Get_Foreign_Updated_At(reloid)
ELSE (SELECT md.updated_at FROM CDB_TableMetadata md WHERE md.tabname = reloid)
END) AS updated_at
FROM fqtn;
$$ LANGUAGE SQL VOLATILE PARALLEL UNSAFE;
-- Return the last updated time of a set of tables
-- It is aware of foreign tables
-- It assumes the local (schema_name, table_name) map to the remote ones with the same name
CREATE OR REPLACE FUNCTION cartodb.CDB_Last_Updated_Time(tables text[])
RETURNS timestamptz AS $$
WITH t AS (
SELECT unnest(tables) AS schema_table_name
), t_oid AS (
SELECT (t.schema_table_name)::regclass::oid as reloid FROM t
), t_updated_at AS (
SELECT
(CASE WHEN relkind = 'f' THEN cartodb.CDB_Get_Foreign_Updated_At(reloid)
ELSE (SELECT md.updated_at FROM CDB_TableMetadata md WHERE md.tabname = reloid)
END) AS updated_at
FROM t_oid
LEFT JOIN pg_catalog.pg_class c ON c.oid = reloid
) SELECT max(updated_at) FROM t_updated_at;
$$ LANGUAGE SQL VOLATILE PARALLEL UNSAFE;

View File

@@ -23,4 +23,4 @@ BEGIN
RETURN line;
END;
$$
LANGUAGE 'plpgsql';
LANGUAGE 'plpgsql' IMMUTABLE STRICT PARALLEL SAFE;

View File

@@ -15,7 +15,7 @@ BEGIN
EXECUTE format('CREATE ROLE %I NOLOGIN;', group_role);
PERFORM cartodb._CDB_Group_CreateGroup_API(group_name, group_role);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Drops group and everything that role owns
-- TODO: LIMITATION: in order to drop a role all its owned objects must be dropped before.
@@ -33,7 +33,7 @@ BEGIN
EXECUTE format('DROP ROLE IF EXISTS %I', group_role);
PERFORM cartodb._CDB_Group_DropGroup_API(group_name);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Renames a group
CREATE OR REPLACE
@@ -48,7 +48,7 @@ BEGIN
EXECUTE format('ALTER ROLE %I RENAME TO %I', old_group_role, new_group_role);
PERFORM cartodb._CDB_Group_RenameGroup_API(old_group_name, new_group_name, new_group_role);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Adds users to a group
CREATE OR REPLACE
@@ -71,7 +71,7 @@ BEGIN
end loop;
PERFORM cartodb._CDB_Group_AddUsers_API(group_name, usernames);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Removes users from a group
CREATE OR REPLACE
@@ -90,7 +90,7 @@ BEGIN
end loop;
PERFORM cartodb._CDB_Group_RemoveUsers_API(group_name, usernames);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
----------------------------------
-- TABLE MANAGEMENT FUNCTIONS
@@ -107,7 +107,7 @@ DECLARE
BEGIN
PERFORM cartodb._CDB_Group_Table_GrantRead(group_name, username, table_name, true);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_Table_GrantRead(group_name text, username text, table_name text, sync boolean)
@@ -122,7 +122,7 @@ BEGIN
PERFORM cartodb._CDB_Group_Table_GrantPermission_API(group_name, username, table_name, 'r');
END IF;
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Grants table write permission to a group
CREATE OR REPLACE
@@ -133,7 +133,7 @@ DECLARE
BEGIN
PERFORM cartodb._CDB_Group_Table_GrantReadWrite(group_name, username, table_name, true);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_Table_GrantReadWrite(group_name text, username text, table_name text, sync boolean)
@@ -149,7 +149,7 @@ BEGIN
PERFORM cartodb._CDB_Group_Table_GrantPermission_API(group_name, username, table_name, 'w');
END IF;
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Granting and revoking permissions on sequences
CREATE OR REPLACE
@@ -175,7 +175,7 @@ BEGIN
END LOOP;
RETURN;
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- Revokes all permissions on a table from a group
CREATE OR REPLACE
@@ -186,7 +186,7 @@ DECLARE
BEGIN
PERFORM cartodb._CDB_Group_Table_RevokeAll(group_name, username, table_name, true);
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_Table_RevokeAll(group_name text, username text, table_name text, sync boolean)
@@ -201,7 +201,7 @@ BEGIN
PERFORM cartodb._CDB_Group_Table_RevokeAllPermission_API(group_name, username, table_name);
END IF;
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-----------------------
-- Helper functions
@@ -223,7 +223,7 @@ BEGIN
END IF;
RETURN group_role;
END
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL STABLE PARALLEL SAFE;
-- Returns the first owner of the schema matching username. Organization user schemas must have one only owner.
CREATE OR REPLACE
@@ -237,7 +237,7 @@ BEGIN
SELECT pg_get_userbyid(nspowner) FROM pg_namespace WHERE nspname = username INTO user_role;
RETURN user_role;
END
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL STABLE PARALLEL SAFE;
-- Database names are too long, we need a shorter version for composing role names
CREATE OR REPLACE
@@ -249,4 +249,4 @@ BEGIN
SELECT md5(current_database()) INTO short_database_name;
RETURN short_database_name;
END
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL STABLE PARALLEL SAFE;

View File

@@ -22,7 +22,7 @@ $$
body = '{ "name": "%s", "database_role": "%s" }' % (group_name, group_role)
query = "select cartodb._CDB_Group_API_Request('POST', '%s', '%s', '{200, 409}') as response_status" % (url, body)
plpy.execute(query)
$$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_DropGroup_API(group_name text)
@@ -35,7 +35,7 @@ $$
query = "select cartodb._CDB_Group_API_Request('DELETE', '%s', '', '{204, 404}') as response_status" % url
plpy.execute(query)
$$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_RenameGroup_API(old_group_name text, new_group_name text, new_group_role text)
@@ -48,7 +48,7 @@ $$
body = '{ "name": "%s", "database_role": "%s" }' % (new_group_name, new_group_role)
query = "select cartodb._CDB_Group_API_Request('PUT', '%s', '%s', '{200, 409}') as response_status" % (url, body)
plpy.execute(query)
$$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_AddUsers_API(group_name text, usernames text[])
@@ -74,7 +74,7 @@ $$
body = "{ \"users\": [\"%s\"] }" % "\",\"".join(usernames)
query = "select cartodb._CDB_Group_API_Request('DELETE', '%s', '%s', '{200, 404}') as response_status" % (url, body)
plpy.execute(query)
$$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
DO LANGUAGE 'plpgsql' $$
BEGIN
@@ -95,7 +95,7 @@ $$
body = '{ "access": "%s" }' % access
query = "select cartodb._CDB_Group_API_Request('PUT', '%s', '%s', '{200, 409}') as response_status" % (url, body)
plpy.execute(query)
$$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
DO LANGUAGE 'plpgsql' $$
BEGIN
@@ -115,7 +115,7 @@ $$
url = '/api/v1/databases/{0}/groups/%s/permission/%s/tables/%s' % (urllib.pathname2url(group_name), username, table_name)
query = "select cartodb._CDB_Group_API_Request('DELETE', '%s', '', '{200, 404}') as response_status" % url
plpy.execute(query)
$$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
DO LANGUAGE 'plpgsql' $$
BEGIN
@@ -146,7 +146,7 @@ $$
params = json.loads(conf)
auth = 'Basic %s' % plpy.execute("SELECT cartodb._CDB_Group_API_Auth('%s', '%s') as auth" % (params['username'], params['password']))[0]['auth']
return { "host": params['host'], "port": params['port'], 'timeout': params['timeout'], 'auth': auth }
$$ LANGUAGE 'plpythonu' VOLATILE;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_API_Auth(username text, password text)
@@ -154,7 +154,7 @@ FUNCTION cartodb._CDB_Group_API_Auth(username text, password text)
$$
import base64
return base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
$$ LANGUAGE 'plpythonu' VOLATILE;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE;
-- url must contain a '%s' placeholder that will be replaced by current_database, for security reasons.
CREATE OR REPLACE
@@ -191,5 +191,5 @@ $$
raise last_err
return None
$$ LANGUAGE 'plpythonu' VOLATILE;
$$ LANGUAGE 'plpythonu' VOLATILE PARALLEL UNSAFE;
revoke all on function cartodb._CDB_Group_API_Request(text, text, text, int[]) from public;

View File

@@ -43,4 +43,4 @@ BEGIN
END LOOP;
RETURN reply;
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql IMMUTABLE PARALLEL SAFE;

View File

@@ -1,3 +1,7 @@
-- Create a sequence that belongs to the schema of the extension.
-- It will be used to generate unique identifiers within the
-- UTF8 safe and length aware. Find a unique identifier with a given prefix
-- and/or suffix and withing a schema. If a schema is not specified, the identifier
-- is guaranteed to be unique for all schemas.
@@ -15,8 +19,8 @@ DECLARE
i INTEGER;
BEGIN
-- Accounts for the _XX incremental suffix in case the identifier is taken
usedspace := 3;
-- Accounts for the XXXX incremental suffix in case the identifier is taken
usedspace := 4;
usedspace := usedspace + coalesce(octet_length(prefix), 0);
usedspace := usedspace + coalesce(octet_length(suffix), 0);
@@ -31,7 +35,7 @@ BEGIN
i := 0;
origident := ident;
WHILE i < 100 LOOP
WHILE i < 10000 LOOP
IF schema IS NOT NULL THEN
SELECT c.relname, n.nspname
INTO rec
@@ -51,13 +55,13 @@ BEGIN
RETURN ident;
END IF;
ident := origident || '_' || i;
ident := origident || i;
i := i + 1;
END LOOP;
PERFORM _CDB_Error('looping too far', '_CDB_Unique_Identifier');
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
-- UTF8 safe and length aware. Find a unique identifier for a column with a given prefix
@@ -76,8 +80,8 @@ DECLARE
i INTEGER;
BEGIN
-- Accounts for the _XX incremental suffix in case the identifier is taken
usedspace := 3;
-- Accounts for the XXXX incremental suffix in case the identifier is taken
usedspace := 4;
usedspace := usedspace + coalesce(octet_length(prefix), 0);
usedspace := usedspace + coalesce(octet_length(suffix), 0);
@@ -92,7 +96,7 @@ BEGIN
i := 0;
origident := ident;
WHILE i < 100 LOOP
WHILE i < 10000 LOOP
SELECT a.attname
INTO rec
FROM pg_class c
@@ -106,13 +110,13 @@ BEGIN
RETURN ident;
END IF;
ident := origident || '_' || i;
ident := origident || i;
i := i + 1;
END LOOP;
PERFORM _CDB_Error('looping too far', '_CDB_Unique_Column_Identifier');
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' VOLATILE PARALLEL SAFE;
-- Truncates a given string to a max_octets octets taking care
@@ -153,4 +157,4 @@ BEGIN
RETURN left(string, (i - 1));
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql' IMMUTABLE PARALLEL SAFE;

View File

@@ -8,7 +8,11 @@ AS $$
SELECT (ST_DumpPoints(ST_ExteriorRing(ST_Buffer($1, $2, 3)))).*
) as points
WHERE path[1] % 2 != 0
$$ LANGUAGE 'sql' IMMUTABLE STRICT;
$$ LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE;
-- In older versions of the extension, CDB_HexagonGrid had a different signature
DROP FUNCTION IF EXISTS cartodb.CDB_HexagonGrid(GEOMETRY, FLOAT8, GEOMETRY);
--
-- Fill given extent with an hexagonal coverage
@@ -25,10 +29,13 @@ $$ LANGUAGE 'sql' IMMUTABLE STRICT;
-- If omitted the origin will be 0,0.
-- The parameter is checked for having the same SRID
-- as the extent.
--
--
-- @param maxcells Optional maximum number of grid cells to generate;
-- if the grid requires more cells to cover the extent
-- and exception will occur.
----
-- DROP FUNCTION IF EXISTS CDB_HexagonGrid(ext GEOMETRY, side FLOAT8);
CREATE OR REPLACE FUNCTION CDB_HexagonGrid(ext GEOMETRY, side FLOAT8, origin GEOMETRY DEFAULT NULL)
CREATE OR REPLACE FUNCTION CDB_HexagonGrid(ext GEOMETRY, side FLOAT8, origin GEOMETRY DEFAULT NULL, maxcells INTEGER DEFAULT 512*512)
RETURNS SETOF GEOMETRY
AS $$
DECLARE
@@ -107,6 +114,12 @@ BEGIN
vstartary := ARRAY[ vstart - (vstep/2.0), vstart ];
END IF;
If maxcells IS NOT NULL AND maxcells > 0 THEN
IF CEIL((CEIL((vend-vstart)/(vstep/2.0)) * CEIL((hend-hstart)/(hstep*2.0/3.0)))/3.0)::integer > maxcells THEN
RAISE EXCEPTION 'The requested grid is too big to be rendered';
END IF;
END IF;
vstartidx := abs(hskip)%2;
RAISE DEBUG 'vstartary: % : %', vstartary[1], vstartary[2];
@@ -132,4 +145,4 @@ BEGIN
RETURN;
END
$$ LANGUAGE 'plpgsql' IMMUTABLE;
$$ LANGUAGE 'plpgsql' IMMUTABLE PARALLEL SAFE;

View File

@@ -117,7 +117,7 @@ BEGIN
RETURN (best_result)[2:array_upper(best_result, 1)];
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql VOLATILE PARALLEL RESTRICTED;
@@ -217,5 +217,5 @@ BEGIN
RETURN array_prepend(gvf, reply);
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql IMMUTABLE PARALLEL SAFE;

View File

@@ -8,16 +8,12 @@
--
CREATE OR REPLACE FUNCTION CDB_LatLng (lat NUMERIC, lng NUMERIC) RETURNS geometry as $$
BEGIN
-- this function is silly
RETURN ST_SetSRID(ST_MakePoint(lng,lat),4326);
END;
$$ language plpgsql IMMUTABLE;
SELECT ST_SetSRID(ST_MakePoint(lng,lat),4326);
$$ language SQL IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION CDB_LatLng (lat FLOAT8, lng FLOAT8) RETURNS geometry as $$
BEGIN
-- this function is silly
RETURN ST_SetSRID(ST_MakePoint(lng,lat),4326);
END;
$$ language plpgsql IMMUTABLE;
SELECT ST_SetSRID(ST_MakePoint(lng,lat),4326);
$$ language SQL IMMUTABLE PARALLEL SAFE;

View File

@@ -13,7 +13,7 @@ $BODY$
ORDER BY COUNT(1) DESC, 1
LIMIT 1;
$BODY$
LANGUAGE 'sql' IMMUTABLE;
LANGUAGE 'sql' IMMUTABLE PARALLEL SAFE;
DROP AGGREGATE IF EXISTS cartodb.CDB_Math_Mode(anyelement);
@@ -21,6 +21,7 @@ CREATE AGGREGATE cartodb.CDB_Math_Mode(anyelement) (
SFUNC=array_append,
STYPE=anyarray,
FINALFUNC=_CDB_Math_final_mode,
PARALLEL = SAFE,
INITCOND='{}'
);

View File

@@ -4,7 +4,7 @@ FUNCTION cartodb.CDB_Organization_Member_Group_Role_Member_Name()
AS $$
SELECT 'cdb_org_member'::text || '_' || md5(current_database());
$$
LANGUAGE SQL IMMUTABLE;
LANGUAGE SQL STABLE PARALLEL SAFE;
DO LANGUAGE 'plpgsql' $$
DECLARE
@@ -25,7 +25,7 @@ AS $$
BEGIN
EXECUTE 'GRANT "' || cartodb.CDB_Organization_Member_Group_Role_Member_Name() || '" TO "' || role_name || '"';
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-------------------------------------------------------------------------------
-- Administrator
@@ -36,7 +36,7 @@ FUNCTION cartodb._CDB_Organization_Admin_Role_Name()
AS $$
SELECT current_database() || '_a'::text;
$$
LANGUAGE SQL IMMUTABLE;
LANGUAGE SQL STABLE PARALLEL SAFE;
-- Administrator role creation on extension install
DO LANGUAGE 'plpgsql' $$
@@ -65,7 +65,7 @@ BEGIN
-- CREATEROLE is not inherited, and is needed for user creation
EXECUTE format('ALTER ROLE %I CREATEROLE', cdb_user_role);
END
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Organization_RemoveAdmin(username text)
@@ -80,7 +80,7 @@ BEGIN
EXECUTE format('ALTER ROLE %I NOCREATEROLE', cdb_user_role);
EXECUTE format('REVOKE %I FROM %I', cdb_admin_role, cdb_user_role);
END
$$ LANGUAGE PLPGSQL;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-------------------------------------------------------------------------------
-- Sharing tables
@@ -93,7 +93,7 @@ BEGIN
EXECUTE 'GRANT USAGE ON SCHEMA "' || from_schema || '" TO "' || to_role_name || '"';
EXECUTE 'GRANT SELECT ON "' || from_schema || '"."' || table_name || '" TO "' || to_role_name || '"';
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Organization_Add_Table_Organization_Read_Permission(from_schema text, table_name text)
@@ -102,7 +102,7 @@ AS $$
BEGIN
EXECUTE 'SELECT cartodb.CDB_Organization_Add_Table_Read_Permission(''' || from_schema || ''', ''' || table_name || ''', ''' || cartodb.CDB_Organization_Member_Group_Role_Member_Name() || ''');';
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Organization_Add_Table_Read_Write_Permission(from_schema text, table_name text, to_role_name text)
@@ -111,8 +111,9 @@ AS $$
BEGIN
EXECUTE 'GRANT USAGE ON SCHEMA "' || from_schema || '" TO "' || to_role_name || '"';
EXECUTE 'GRANT SELECT, INSERT, UPDATE, DELETE ON "' || from_schema || '"."' || table_name || '" TO "' || to_role_name || '"';
EXECUTE 'GRANT USAGE, SELECT ON SEQUENCE ' || pg_catalog.pg_get_serial_sequence(Format('%I.%I', from_schema, table_name), 'cartodb_id') || ' TO "' || to_role_name || '"';
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Organization_Add_Table_Organization_Read_Write_Permission(from_schema text, table_name text)
@@ -121,7 +122,7 @@ AS $$
BEGIN
EXECUTE 'SELECT cartodb.CDB_Organization_Add_Table_Read_Write_Permission(''' || from_schema || ''', ''' || table_name || ''', ''' || cartodb.CDB_Organization_Member_Group_Role_Member_Name() || ''');';
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
@@ -134,7 +135,7 @@ BEGIN
-- We need to revoke usage on schema only if we are revoking privileges from the last table where to_role_name has
-- any permission granted within the schema from_schema
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Organization_Remove_Organization_Access_Permission(from_schema text, table_name text)
@@ -143,4 +144,4 @@ AS $$
BEGIN
EXECUTE 'SELECT cartodb.CDB_Organization_Remove_Access_Permission(''' || from_schema || ''', ''' || table_name || ''', ''' || cartodb.CDB_Organization_Member_Group_Role_Member_Name() || ''');';
END
$$ LANGUAGE PLPGSQL VOLATILE;
$$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,173 @@
-- Auxiliary overviews FUNCTIONS
-- Maximum zoom level for which overviews may be created
CREATE OR REPLACE FUNCTION _CDB_MaxOverviewLevel()
RETURNS INTEGER
AS $$
BEGIN
-- Zoom level will be limited so that both tile coordinates
-- and gridding coordinates within a tile up to 1px
-- (i.e. tile coordinates / 256)
-- can be stored in a 32-bit signed integer.
-- We have 31 bits por positive numbers
-- For zoom level Z coordinates range from 0 to 2^Z-1, so they
-- need Z bits, and need 8 bits more to address pixels within a tile
-- (gridding), so we'll limit Z to a maximum of 31 - 8
RETURN 23;
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- Maximum zoom level usable with integer coordinates
CREATE OR REPLACE FUNCTION _CDB_MaxZoomLevel()
RETURNS INTEGER
AS $$
BEGIN
RETURN 31;
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- Information about tables in a schema.
-- If the schema name parameter is NULL, then tables from all schemas
-- that may contain user tables are returned.
-- For each table, the regclass, schema name and table name are returned.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_UserTablesInSchema(schema_name text DEFAULT NULL)
RETURNS TABLE(table_regclass REGCLASS, schema_name TEXT, table_name TEXT)
AS $$
SELECT
c.oid::regclass AS table_regclass,
n.nspname::text AS schema_name,
c.relname::text AS table_relname
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND c.relname NOT IN ('cdb_tablemetadata', 'cdb_analysis_catalog', 'cdb_conf', 'spatial_ref_sys')
AND CASE WHEN schema_name IS NULL
THEN n.nspname NOT IN ('pg_catalog', 'information_schema', 'topology', 'cartodb')
ELSE n.nspname = schema_name
END;
$$ LANGUAGE 'sql' STABLE PARALLEL SAFE;
-- Pattern that can be used to detect overview tables and Extract
-- the intended zoom level from the table name.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_OverviewTableDiscriminator()
RETURNS TEXT
AS $$
BEGIN
RETURN '\A_vovw_(\d+)_';
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- substring(tablename from _CDB_OverviewTableDiscriminator())
-- Pattern matched by the overview tables of a given base table name.
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_OverviewTablePattern(base_table TEXT)
RETURNS TEXT
AS $$
BEGIN
RETURN _CDB_OverviewTableDiscriminator() || base_table;
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- tablename SIMILAR TO _CDB_OverviewTablePattern(base_table)
-- Name of an overview table, given the base table name and the Z level
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_OverviewTableName(base_table TEXT, z INTEGER)
RETURNS TEXT
AS $$
BEGIN
RETURN '_vovw_' || z::text || '_' || base_table;
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- Condition to check if a tabla is an overview table of some base table
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_IsOverviewTableOf(base_table TEXT, otable TEXT)
RETURNS BOOLEAN
AS $$
BEGIN
RETURN otable SIMILAR TO _CDB_OverviewTablePattern(base_table);
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- Extract the Z level from an overview table name
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_OverviewTableZ(otable TEXT)
RETURNS INTEGER
AS $$
BEGIN
RETURN substring(otable from _CDB_OverviewTableDiscriminator())::integer;
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- Name of the base table corresponding to an overview table
-- Scope: private.
CREATE OR REPLACE FUNCTION _CDB_OverviewBaseTableName(overview_table TEXT)
RETURNS TEXT
AS $$
BEGIN
IF _CDB_OverviewTableZ(overview_table) IS NULL THEN
RETURN overview_table;
ELSE
RETURN regexp_replace(overview_table, _CDB_OverviewTableDiscriminator(), '');
END IF;
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _CDB_OverviewBaseTable(overview_table REGCLASS)
RETURNS REGCLASS
AS $$
DECLARE
table_name TEXT;
schema_name TEXT;
base_name TEXT;
base_table REGCLASS;
BEGIN
SELECT * FROM _cdb_split_table_name(overview_table) INTO schema_name, table_name;
base_name := _CDB_OverviewBaseTableName(table_name);
IF base_name != table_name THEN
base_table := Format('%I.%I', schema_name, base_name)::regclass;
ELSE
base_table := overview_table;
END IF;
RETURN base_table;
END;
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- Schema and relation names of a table given its reloid
-- Scope: private.
-- Parameters
-- reloid: oid of the table.
-- Return (schema_name, table_name)
-- note that returned names will be quoted if necessary
CREATE OR REPLACE FUNCTION _cdb_split_table_name(reloid REGCLASS, OUT schema_name TEXT, OUT table_name TEXT)
AS $$
BEGIN
SELECT n.nspname, c.relname
INTO STRICT schema_name, table_name
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.oid = reloid;
END
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;
-- Schema and relation names of a table given its reloid
-- Scope: private.
-- Parameters
-- reloid: oid of the table.
-- Return (schema_name, table_name)
-- note that returned names will be quoted if necessary
CREATE OR REPLACE FUNCTION _cdb_schema_name(reloid REGCLASS)
RETURNS TEXT
AS $$
DECLARE
schema_name TEXT;
BEGIN
SELECT n.nspname
INTO STRICT schema_name
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.oid = reloid;
RETURN schema_name;
END
$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE;

View File

@@ -5,39 +5,14 @@
-- bins based on the Quantile method.
--
-- @param breaks The number of bins you want to find.
--
--
CREATE OR REPLACE FUNCTION CDB_QuantileBins ( in_array NUMERIC[], breaks INT) RETURNS NUMERIC[] as $$
DECLARE
element_count INT4;
break_size numeric;
tmp_val numeric;
i INT := 1;
reply numeric[];
BEGIN
-- sort our values
SELECT array_agg(e) INTO in_array FROM (SELECT unnest(in_array) e ORDER BY e ASC) x;
-- get the total size of our data
element_count := array_length(in_array, 1);
break_size := element_count::numeric / breaks;
-- slice our bread
LOOP
IF i < breaks THEN
IF break_size * i % 1 > 0 THEN
SELECT e INTO tmp_val FROM ( SELECT unnest(in_array) e LIMIT 1 OFFSET ceil(break_size * i) - 1) x;
ELSE
SELECT avg(e) INTO tmp_val FROM ( SELECT unnest(in_array) e LIMIT 2 OFFSET ceil(break_size * i) - 1 ) x;
END IF;
ELSIF i = breaks THEN
-- select the last value
SELECT max(e) INTO tmp_val FROM ( SELECT unnest(in_array) e ) x;
ELSE
EXIT;
END IF;
reply = array_append(reply, tmp_val);
i := i+1;
END LOOP;
RETURN reply;
END;
$$ language plpgsql IMMUTABLE;
--
CREATE OR REPLACE FUNCTION CDB_QuantileBins(in_array numeric[], breaks int)
RETURNS numeric[]
AS $$
SELECT
percentile_disc(Array(SELECT generate_series(1, breaks) / breaks::numeric))
WITHIN GROUP (ORDER BY x ASC) AS p
FROM
unnest(in_array) AS x;
$$ language SQL IMMUTABLE STRICT PARALLEL SAFE;

View File

@@ -11,4 +11,4 @@ RETURNS SETOF TEXT AS $$
cleaned = match[0].strip()
if ( cleaned ):
yield cleaned
$$ language 'plpythonu' IMMUTABLE STRICT;
$$ language 'plpythonu' IMMUTABLE STRICT PARALLEL SAFE;

View File

@@ -64,7 +64,7 @@ BEGIN
return tables;
END
$$ LANGUAGE 'plpgsql' VOLATILE STRICT;
$$ LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL UNSAFE;
-- Keep CDB_QueryTables with same signature for backwards compatibility.
@@ -75,4 +75,4 @@ AS $$
BEGIN
RETURN CDB_QueryTablesText(query)::name[];
END
$$ LANGUAGE 'plpgsql' VOLATILE STRICT;
$$ LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL UNSAFE;

View File

@@ -12,7 +12,7 @@ BEGIN
RETURN relation_size;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
-- Return the estimated size of user data. Used for quota checking.
CREATE OR REPLACE FUNCTION CDB_UserDataSize(schema_name TEXT)
@@ -26,16 +26,15 @@ BEGIN
WHERE o_table_schema = schema_name AND o_table_catalog = current_database()
),
user_tables AS (
SELECT table_name FROM information_schema.tables
WHERE table_catalog = current_database() AND table_schema = schema_name
AND table_name != 'spatial_ref_sys'
AND table_name != 'cdb_tablemetadata'
AND table_type = 'BASE TABLE'
SELECT table_name FROM _CDB_NonAnalysisTablesInSchema(schema_name)
),
table_cat AS (
SELECT
table_name,
EXISTS(select * from raster_tables where o_table_name = table_name) AS is_overview,
(
EXISTS(select * from raster_tables where o_table_name = table_name)
OR table_name SIMILAR TO _CDB_OverviewTableDiscriminator() || '[\w\d]*'
) AS is_overview,
EXISTS(SELECT * FROM raster_tables WHERE r_table_name = table_name) AS is_raster
FROM user_tables
),
@@ -56,7 +55,7 @@ BEGIN
END IF;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
-- Return the estimated size of user data. Used for quota checking.
@@ -64,9 +63,9 @@ LANGUAGE 'plpgsql' VOLATILE;
CREATE OR REPLACE FUNCTION CDB_UserDataSize()
RETURNS bigint AS
$$
SELECT public.CDB_UserDataSize('public');
SELECT CDB_UserDataSize('public');
$$
LANGUAGE 'sql' VOLATILE;
LANGUAGE 'sql' VOLATILE PARALLEL UNSAFE;
-- Triggers cannot have declared arguments: pbfact float8, qmax int8, schema_name text
CREATE OR REPLACE FUNCTION CDB_CheckQuota()
@@ -122,7 +121,7 @@ BEGIN
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION CDB_SetUserQuotaInBytes(schema_name text, bytes int8)
@@ -143,7 +142,7 @@ BEGIN
return bytes;
END
$$
LANGUAGE 'plpgsql' VOLATILE STRICT;
LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL UNSAFE;
CREATE OR REPLACE FUNCTION CDB_SetUserQuotaInBytes(bytes int8)
@@ -153,4 +152,4 @@ BEGIN
return public.CDB_SetUserQuotaInBytes('public', bytes);
END;
$$
LANGUAGE 'plpgsql' VOLATILE STRICT;
LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL UNSAFE;

View File

@@ -64,6 +64,6 @@ BEGIN
RETURN tidlist;
END
$$ LANGUAGE 'plpgsql' STABLE STRICT;
$$ LANGUAGE 'plpgsql' STABLE STRICT PARALLEL SAFE;
-- }

View File

@@ -1,3 +1,6 @@
-- In older versions of the extension, CDB_RectangleGrid had a different signature
DROP FUNCTION IF EXISTS cartodb.CDB_RectangleGrid(GEOMETRY, FLOAT8, FLOAT8, GEOMETRY);
--
-- Fill given extent with a rectangular coverage
--
@@ -6,7 +9,7 @@
-- be emitted. The returned hexagons will have the same SRID
-- as this extent.
--
-- @param width With of each rectangle
-- @param width Width of each rectangle
--
-- @param height Height of each rectangle
--
@@ -14,9 +17,12 @@
-- If omitted the origin will be 0,0.
-- The parameter is checked for having the same SRID
-- as the extent.
--
--
CREATE OR REPLACE FUNCTION CDB_RectangleGrid(ext GEOMETRY, width FLOAT8, height FLOAT8, origin GEOMETRY DEFAULT NULL)
-- @param maxcells Optional maximum number of grid cells to generate;
-- if the grid requires more cells to cover the extent
-- and exception will occur.
--
CREATE OR REPLACE FUNCTION CDB_RectangleGrid(ext GEOMETRY, width FLOAT8, height FLOAT8, origin GEOMETRY DEFAULT NULL, maxcells INTEGER DEFAULT 512*512)
RETURNS SETOF GEOMETRY
AS $$
DECLARE
@@ -79,6 +85,12 @@ BEGIN
--RAISE DEBUG 'hend: %', hend;
--RAISE DEBUG 'vend: %', vend;
If maxcells IS NOT NULL AND maxcells > 0 THEN
IF ((hend - hstart)/hstep * (vend - vstart)/vstep)::integer > maxcells THEN
RAISE EXCEPTION 'The requested grid is too big to be rendered';
END IF;
END IF;
x := hstart;
WHILE x < hend LOOP -- over X
y := vstart;
@@ -93,4 +105,4 @@ BEGIN
RETURN;
END
$$ LANGUAGE 'plpgsql' IMMUTABLE;
$$ LANGUAGE 'plpgsql' IMMUTABLE PARALLEL SAFE;

View File

@@ -4,7 +4,7 @@
-- @param in_array A numeric array of numbers
--
-- Returns: statistical quantity chosen
--
--
-- References: http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
--
@@ -13,35 +13,41 @@ CREATE OR REPLACE FUNCTION CDB_Kurtosis ( in_array NUMERIC[] ) RETURNS NUMERIC a
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;
SELECT AVG(e), COUNT(e)::numeric * power(stddev(e),4) INTO a, c 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;
IF c=0 THEN
RETURN 0;
ELSE
RETURN k;
EXECUTE 'SELECT sum(power($1 - e, 4)) / ($2 ) - 3
FROM (SELECT unnest($3) e ) x'
INTO k
USING a, c, in_array;
RETURN k;
END IF;
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql IMMUTABLE STRICT PARALLEL SAFE;
-- 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;
SELECT AVG(e), COUNT(e)::numeric * power(stddev(e),3) INTO a, c FROM ( SELECT unnest(in_array) e ) x;
IF c=0 THEN
RETURN 0;
ELSE
EXECUTE 'SELECT sum(power($1 - e, 3)) / ( $2 )
FROM (SELECT unnest($3) e ) x'
INTO sk
USING a, c, in_array;
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;
RETURN sk;
END IF;
END;
$$ language plpgsql IMMUTABLE;
$$ language plpgsql IMMUTABLE STRICT PARALLEL SAFE;

View File

@@ -17,4 +17,4 @@ BEGIN
RETURN output;
END;
$$
LANGUAGE 'plpgsql' STABLE STRICT;
LANGUAGE 'plpgsql' IMMUTABLE STRICT PARALLEL UNSAFE;

View File

@@ -20,7 +20,7 @@ AS $$
AND pg_class.relname=pg_indexes.indexname
;
$$ LANGUAGE SQL;
$$ LANGUAGE SQL STABLE PARALLEL SAFE;
-- This is to migrate from pre-0.2.0 version
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36

View File

@@ -5,6 +5,11 @@ CREATE TABLE IF NOT EXISTS
updated_at timestamp with time zone not null default now()
);
CREATE OR REPLACE VIEW public.CDB_TableMetadata_Text AS
SELECT FORMAT('%I.%I', n.nspname::text, c.relname::text) tabname, updated_at
FROM public.CDB_TableMetadata, pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid;
-- No one can see this
-- Updates are only possible trough the security definer trigger
-- GRANT SELECT ON public.CDB_TableMetadata TO public;
@@ -51,7 +56,7 @@ BEGIN
RETURN NULL;
END;
$$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
--
-- Trigger invalidating varnish whenever CDB_TableMetadata
@@ -61,13 +66,11 @@ CREATE OR REPLACE FUNCTION _CDB_TableMetadata_Updated()
RETURNS trigger AS
$$
DECLARE
tabname TEXT;
tabname regclass;
rec RECORD;
found BOOL;
function_start timestamptz;
function_end timestamptz;
function_duration float;
log_error_verbosity_value text;
schema_name TEXT;
table_name TEXT;
BEGIN
IF TG_OP = 'UPDATE' or TG_OP = 'INSERT' THEN
@@ -76,8 +79,6 @@ BEGIN
tabname = OLD.tabname;
END IF;
function_start := clock_timestamp();
-- Notify table data update
-- This needs a little bit more of research regarding security issues
-- see https://github.com/CartoDB/cartodb/pull/241
@@ -104,31 +105,25 @@ BEGIN
AND u.usesuper
ORDER BY n.nspname
LOOP
SELECT n.nspname, c.relname FROM pg_class c, pg_namespace n WHERE c.oid=tabname AND c.relnamespace = n.oid INTO schema_name, table_name;
EXECUTE 'SELECT ' || quote_ident(rec.nspname) || '.'
|| quote_ident(rec.proname)
|| '(' || quote_literal(tabname) || ')';
|| '(' || quote_literal(quote_ident(schema_name) || '.' || quote_ident(table_name)) || ')';
found := true;
EXIT;
END LOOP;
IF NOT found THEN RAISE WARNING 'Missing cdb_invalidate_varnish()'; END IF;
function_end := clock_timestamp();
SELECT extract(epoch from (function_end - function_start)) INTO function_duration;
SELECT setting INTO log_error_verbosity_value FROM pg_settings WHERE name='log_error_verbosity';
SET log_error_verbosity=TERSE;
RAISE LOG 'invalidation_duration: %', function_duration::text;
PERFORM 'SET log_error_verbosity= ' || log_error_verbosity_value;
RETURN NULL;
END;
$$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
LANGUAGE plpgsql VOLATILE PARALLEL UNSAFE SECURITY DEFINER;
DROP TRIGGER IF EXISTS table_modified ON CDB_TableMetadata;
DROP TRIGGER IF EXISTS table_modified ON public.CDB_TableMetadata;
-- NOTE: on DELETE we would be unable to convert the table
-- oid (regclass) to its name
CREATE TRIGGER table_modified AFTER INSERT OR UPDATE
ON CDB_TableMetadata FOR EACH ROW EXECUTE PROCEDURE
ON public.CDB_TableMetadata FOR EACH ROW EXECUTE PROCEDURE
_CDB_TableMetadata_Updated();
@@ -148,4 +143,4 @@ CREATE OR REPLACE FUNCTION public.CDB_TableMetadataTouch(tablename regclass)
WHERE NOT EXISTS (SELECT * FROM upsert);
END;
$$
LANGUAGE 'plpgsql' VOLATILE STRICT;
LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL UNSAFE;

View File

@@ -53,7 +53,7 @@ BEGIN
WHEN OTHERS THEN
-- See http://github.com/Vizzuality/cartodb/issues/931
RAISE WARNING 'Could not clean input geometry: %', SQLERRM;
RETURN NULL;
RETURN NULL;
END;
latlon_input := ST_CollectionExtract(latlon_input, ST_Dimension(geom)+1);
END IF;
@@ -75,4 +75,4 @@ BEGIN
RETURN ret;
END
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT PARALLEL UNSAFE;

View File

@@ -14,14 +14,14 @@ SELECT c.relname
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND c.relname NOT IN ('cdb_tablemetadata', 'spatial_ref_sys')
AND c.relname NOT IN ('cdb_tablemetadata', 'cdb_analysis_catalog', 'cdb_conf', 'spatial_ref_sys')
AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'topology', 'cartodb')
AND CASE WHEN perm = 'public' THEN has_table_privilege('publicuser', c.oid, 'SELECT')
WHEN perm = 'private' THEN has_table_privilege(current_user, c.oid, 'SELECT') AND NOT has_table_privilege('publicuser', c.oid, 'SELECT')
WHEN perm = 'all' THEN has_table_privilege(current_user, c.oid, 'SELECT') OR has_table_privilege('publicuser', c.oid, 'SELECT')
ELSE false END;
$$ LANGUAGE 'sql';
$$ LANGUAGE 'sql' STABLE PARALLEL SAFE;
-- This is to migrate from pre-0.2.0 version
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36

View File

@@ -1,28 +1,12 @@
-- {
-- Return pixel resolution at the given zoom level
-- }{
CREATE OR REPLACE FUNCTION CDB_XYZ_Resolution(z INTEGER)
RETURNS FLOAT8
AS $$
DECLARE
earth_circumference FLOAT8;
tile_size INTEGER;
full_resolution FLOAT8;
BEGIN
-- Earth equatorial circumference in meters (according to wikipedia)
earth_circumference := 40075017;
-- Size of each tile in pixels (1:1 aspect ratio)
tile_size := 256;
full_resolution := earth_circumference/tile_size;
RETURN full_resolution / (power(2,z));
END
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
-- circumference divided by 256 is z0 resolution, then divide by 2^z
SELECT 6378137.0*2.0*pi() / 256.0 / power(2.0, z);
$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE STRICT;
-- }
-- {
@@ -73,7 +57,6 @@ BEGIN
--RAISE DEBUG 'ymax: %', ymax;
RETURN ST_MakeEnvelope(xmin, ymin, xmax, ymax, 3857);
END
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT PARALLEL SAFE;
-- }

View File

@@ -1,31 +1,36 @@
CREATE OR REPLACE FUNCTION cartodb.CDB_ZoomFromScale(scaleDenominator numeric) RETURNS int AS $$
BEGIN
CASE
WHEN scaleDenominator > 1000000000 THEN RETURN 0;
WHEN scaleDenominator <= 1000000000 AND scaleDenominator > 500000000 THEN RETURN 1;
WHEN scaleDenominator <= 500000000 AND scaleDenominator > 200000000 THEN RETURN 2;
WHEN scaleDenominator <= 200000000 AND scaleDenominator > 100000000 THEN RETURN 3;
WHEN scaleDenominator <= 100000000 AND scaleDenominator > 50000000 THEN RETURN 3;
WHEN scaleDenominator <= 50000000 AND scaleDenominator > 25000000 THEN RETURN 4;
WHEN scaleDenominator <= 25000000 AND scaleDenominator > 12500000 THEN RETURN 5;
WHEN scaleDenominator <= 12500000 AND scaleDenominator > 6500000 THEN RETURN 6;
WHEN scaleDenominator <= 6500000 AND scaleDenominator > 3000000 THEN RETURN 7;
WHEN scaleDenominator <= 3000000 AND scaleDenominator > 1500000 THEN RETURN 8;
WHEN scaleDenominator <= 1500000 AND scaleDenominator > 750000 THEN RETURN 9;
WHEN scaleDenominator <= 750000 AND scaleDenominator > 400000 THEN RETURN 10;
WHEN scaleDenominator <= 400000 AND scaleDenominator > 200000 THEN RETURN 11;
WHEN scaleDenominator <= 200000 AND scaleDenominator > 100000 THEN RETURN 12;
WHEN scaleDenominator <= 100000 AND scaleDenominator > 50000 THEN RETURN 13;
WHEN scaleDenominator <= 50000 AND scaleDenominator > 25000 THEN RETURN 14;
WHEN scaleDenominator <= 25000 AND scaleDenominator > 12500 THEN RETURN 15;
WHEN scaleDenominator <= 12500 AND scaleDenominator > 5000 THEN RETURN 16;
WHEN scaleDenominator <= 5000 AND scaleDenominator > 2500 THEN RETURN 17;
WHEN scaleDenominator <= 2500 AND scaleDenominator > 1500 THEN RETURN 18;
WHEN scaleDenominator <= 1500 AND scaleDenominator > 750 THEN RETURN 19;
WHEN scaleDenominator <= 750 AND scaleDenominator > 500 THEN RETURN 20;
WHEN scaleDenominator <= 500 AND scaleDenominator > 250 THEN RETURN 21;
WHEN scaleDenominator <= 250 AND scaleDenominator > 100 THEN RETURN 22;
WHEN scaleDenominator <= 100 THEN RETURN 23;
END CASE;
END
$$ LANGUAGE plpgsql IMMUTABLE;
-- Maximum supported zoom level
CREATE OR REPLACE FUNCTION _CDB_MaxSupportedZoom()
RETURNS int
LANGUAGE SQL
IMMUTABLE PARALLEL SAFE
AS $$
-- The maximum zoom level has to be limited for various reasons,
-- e.g. zoom levels greater than 31 would require tile coordinates
-- that would not fit in an INTEGER (which is signed, 32 bits long).
-- We'll choose 20 as a limit which is safe also when the JavaScript shift
-- operator (<<) is used for computing powers of two.
SELECT 29;
$$;
CREATE OR REPLACE FUNCTION cartodb.CDB_ZoomFromScale(scaleDenominator numeric)
RETURNS int
LANGUAGE SQL
IMMUTABLE PARALLEL SAFE
AS $$
SELECT
CASE
WHEN scaleDenominator > 600000000 THEN
-- Scale is smaller than zoom level 0
NULL
WHEN scaleDenominator = 0 THEN
-- Actual zoom level would be infinite
_CDB_MaxSupportedZoom()
ELSE
CAST (
LEAST(
ROUND(LOG(2, 559082264.028/scaleDenominator)),
_CDB_MaxSupportedZoom()
)
AS INTEGER)
END;
$$;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,102 +0,0 @@
\set VERBOSITY terse
-- Set user quota to infinite
SELECT CDB_SetUserQuotaInBytes(0);
-- Enable ddl triggers
SELECT cartodb.cdb_enable_ddl_hooks();
create schema c;
SELECT CDB_SetUserQuotaInBytes('c', 0);
DROP USER IF EXISTS cartodb_postgresql_unpriv_user;
CREATE USER cartodb_postgresql_unpriv_user;
GRANT ALL ON SCHEMA c to cartodb_postgresql_unpriv_user;
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
--SELECT session_user, current_user;
----------------------
-- CREATE TABLE
----------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select 1 as i INTO c.t3;
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)) as age
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
-- Table with cartodb_id field, see
-- http://github.com/CartoDB/cartodb-postgresql/issues/32
select 1 as cartodb_id INTO c.t4;
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)) as age
FROM CDB_TableMetadata WHERE tabname = 'c.t4'::regclass;
----------------------------
-- ALTER TABLE RENAME COLUMN
----------------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
alter table c.t3 rename column the_geom_webmercator to webmerc;
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
alter table c.t3 rename column the_geom_webmercator to webmerc2;
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
----------------------------
-- ALTER TABLE DROP COLUMN
----------------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
alter table c.t3 drop column the_geom_webmercator;
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
----------------------------
-- ALTER TABLE ADD COLUMN
----------------------------
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';
select pg_sleep(.1);
alter table c.t3 add column id2 int;
RESET SESSION AUTHORIZATION;
select
tabname::text,
round(extract('secs' from now() - updated_at)*10) as agecs
FROM CDB_TableMetadata WHERE tabname = 'c.t3'::regclass;
----------------------------
-- DROP TABLE
----------------------------
RESET SESSION AUTHORIZATION;
drop schema c cascade;
select count(*) from CDB_TableMetadata;
DROP OWNED BY cartodb_postgresql_unpriv_user;
DROP ROLE cartodb_postgresql_unpriv_user;
DROP FUNCTION _CDB_UserQuotaInBytes();

View File

@@ -1,5 +1,4 @@
CREATE EXTENSION postgis;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION plpythonu;
CREATE EXTENSION cartodb;
CREATE FUNCTION public.cdb_invalidate_varnish(table_name text)
@@ -7,4 +6,4 @@ RETURNS void AS $$
BEGIN
RAISE NOTICE 'cdb_invalidate_varnish(%) called', table_name;
END;
$$ LANGUAGE 'plpgsql';
$$ LANGUAGE 'plpgsql';

View File

@@ -0,0 +1,20 @@
SET client_min_messages TO error;
\set VERBOSITY terse
SELECT CDB_SetUserQuotaInBytes(1000000);
SELECT _CDB_AnalysisTablesInSchema('public');
SELECT _CDB_AnalysisDataSize('public');
CREATE TABLE analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d5(id int);
CREATE TABLE analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da94(id int);
CREATE TABLE analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da9(id int);
SELECT _CDB_AnalysisTablesInSchema('public');
SELECT _CDB_AnalysisDataSize('public');
SELECT CDB_CheckAnalysisQuota('analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da94');
SELECT CDB_SetUserQuotaInBytes(1);
SELECT CDB_CheckAnalysisQuota('analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da94');
INSERT INTO analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d5(id) VALUES (1),(2),(3),(4),(5);
SELECT CDB_CheckAnalysisQuota('analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da94');
DROP TABLE analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d5;
DROP TABLE analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da94;
DROP TABLE analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da9;
DROP FUNCTION "public"._CDB_UserQuotaInBytes();

View File

@@ -0,0 +1,18 @@
SET
1000000
0
CREATE TABLE
CREATE TABLE
CREATE TABLE
(analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d5,public,analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d5)
(analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da94,public,analysis_2f13a3dbd7_f00cee44e9e6152b450bde3a92eb9ae0d099da94)
0
1
INSERT 0 5
ERROR: Analysis cache space limits exceeded
DROP TABLE
DROP TABLE
DROP TABLE
DROP FUNCTION

View File

@@ -1,5 +1,5 @@
SET client_min_messages TO error;
\set VERBOSITY default
\set VERBOSITY terse
CREATE OR REPLACE FUNCTION CDB_CartodbfyTableCheck(tabname regclass, label text)
RETURNS text AS
@@ -124,13 +124,21 @@ END;
$$
LANGUAGE 'plpgsql';
-- table with single non-geometrical column
-- check cartodbfytable idempotence
CREATE TABLE t AS SELECT 1::int as a;
SELECT CDB_CartodbfyTable('public', 't'); -- should fail
SELECT CDB_SetUserQuotaInBytes(0); -- Set user quota to infinite
SELECT CDB_CartodbfyTableCheck('t', 'single non-geometrical column');
DROP TABLE t;
-- table with single non-geometrical column
CREATE TABLE t AS SELECT ST_SetSRID(ST_MakePoint(-1,-1),4326) as the_geom, 1::int as cartodb_id, 'this is a sentence' as description;
SELECT CDB_CartodbfyTableCheck('t', 'check function idempotence');
SELECT * FROM t;
SELECT CDB_CartodbfyTableCheck('t', 'check function idempotence');
SELECT * FROM t;
DROP TABLE t;
-- table with existing srid-unconstrained (but type-constrained) the_geom
CREATE TABLE t AS SELECT ST_SetSRID(ST_MakePoint(0,0),4326)::geometry(point) as the_geom;
SELECT CDB_CartodbfyTableCheck('t', 'srid-unconstrained the_geom');
@@ -164,19 +172,22 @@ SELECT CDB_CartodbfyTableCheck('t', 'trigger-protected the_geom');
SELECT 'extent',ST_Extent(ST_SnapToGrid(the_geom,0.2)) FROM t;
DROP TABLE t;
-- INFO: disabled because cartodbfy does not longer consider text columns for primary ID
-- -- table with existing cartodb_id field of type text
-- CREATE TABLE t AS SELECT 10::text as cartodb_id;
-- SELECT CDB_CartodbfyTableCheck('t', 'text cartodb_id');
-- select cartodb_id/2 FROM t;
-- DROP TABLE t;
-- table with existing cartodb_id field of type text
CREATE TABLE t AS SELECT 10::text as cartodb_id;
SELECT CDB_CartodbfyTableCheck('t', 'text cartodb_id');
select cartodb_id/2 FROM t;
DROP TABLE t;
-- INFO: disabled because cartodbfy does not longer consider text columns for primary ID
-- -- table with existing cartodb_id field of type text not casting
-- CREATE TABLE t AS SELECT 'nan' as cartodb_id;
-- SELECT CDB_CartodbfyTableCheck('t', 'uncasting text cartodb_id');
-- select cartodb_id,_cartodb_id0 FROM t;
-- DROP TABLE t;
-- table with existing cartodb_id field of type text not casting
CREATE TABLE t AS SELECT 'nan'::text as cartodb_id;
SELECT CDB_CartodbfyTableCheck('t', 'uncasting text cartodb_id');
DROP TABLE t;
-- table with empty cartodb_id field of type text
CREATE TABLE t AS SELECT null::text as cartodb_id;
SELECT CDB_CartodbfyTableCheck('t', 'empty text cartodb_id');
SELECT cartodb_id from t;
DROP TABLE t;
-- table with existing cartodb_id field of type int4 not sequenced
CREATE TABLE t AS SELECT 1::int4 as cartodb_id;
@@ -291,7 +302,7 @@ INSERT INTO test VALUES
(NULL),
(3);
SELECT CDB_CartodbfyTableCheck('test', 'Table with null cartodb_id #148');
SELECT cartodb_id, cartodb_id_0 from test;
SELECT cartodb_id from test;
DROP TABLE test;
-- Table with non unique cartodb_id
@@ -303,7 +314,7 @@ INSERT INTO test VALUES
(2),
(2);
SELECT CDB_CartodbfyTableCheck('test', 'Table with non unique cartodb_id #148');
SELECT cartodb_id, cartodb_id_0 from test;
SELECT cartodb_id from test;
DROP TABLE test;
-- Table with non unique and null cartodb_id
@@ -316,7 +327,7 @@ INSERT INTO test VALUES
(NULL),
(2);
SELECT CDB_CartodbfyTableCheck('test', 'Table with non unique and null cartodb_id #148');
SELECT cartodb_id, cartodb_id_0 from test;
SELECT cartodb_id from test;
DROP TABLE test;
CREATE TABLE test (
@@ -361,6 +372,24 @@ SELECT column_name FROM information_schema.columns WHERE table_name = 'test' AND
DROP TABLE test;
SET client_min_messages TO error;
-- Unique identifier generation can break CDB_CartodbfyTable #305
BEGIN;
DO $$
BEGIN
FOR i IN 1..150 LOOP
EXECUTE 'CREATE TABLE untitled_table();';
EXECUTE $query$SELECT CDB_CartodbfyTable('untitled_table');$query$;
EXECUTE 'ALTER TABLE untitled_table RENAME TO my_renamed_table_' || i;
END LOOP;
END;
$$;
ROLLBACK;
-- Long table name could cause possible sequence rename collision #325
CREATE TABLE "wadus_table_9473e8f6-2da1-11e8-8bca-0204e4dfe4d8" ( cartodb_id serial primary key );
SELECT CDB_CartodbfyTableCheck('wadus_table_9473e8f6-2da1-11e8-8bca-0204e4dfe4d8'::REGCLASS, 'Long table name could cause sequence collision while renaming #325');
DROP TABLE "wadus_table_9473e8f6-2da1-11e8-8bca-0204e4dfe4d8";
-- TODO: table with existing custom-triggered the_geom
DROP FUNCTION CDB_CartodbfyTableCheck(regclass, text);

View File

@@ -2,12 +2,16 @@ SET
CREATE FUNCTION
SELECT 1
ERROR: Please set user quota before cartodbfying tables.
CONTEXT: SQL statement "SELECT cartodb._CDB_check_prerequisites(destschema, reloid)"
PL/pgSQL function cdb_cartodbfytable(text,regclass) line 21 at PERFORM
0
single non-geometrical column cartodbfied fine
DROP TABLE
SELECT 1
check function idempotence cartodbfied fine
1|0101000020E6100000000000000000F0BF000000000000F0BF|0101000020110F0000DB0B4ADA772DFBC077432E49D22DFBC0|this is a sentence
check function idempotence cartodbfied fine
1|0101000020E6100000000000000000F0BF000000000000F0BF|0101000020110F0000DB0B4ADA772DFBC077432E49D22DFBC0|this is a sentence
DROP TABLE
SELECT 1
srid-unconstrained the_geom cartodbfied fine
DROP TABLE
SELECT 2
@@ -26,6 +30,17 @@ SELECT 1
CREATE TRIGGER
trigger-protected the_geom cartodbfied fine
extent|BOX(1 1,2 2)
DROP TABLE
SELECT 1
text cartodb_id cartodbfied fine
5
DROP TABLE
SELECT 1
ERROR: CDB(_CDB_Has_Usable_Primary_ID: Error: invalid cartodb_id, cartodb_id): ALTER TABLE t ADD CONSTRAINT cartodb_id_pk PRIMARY KEY (cartodb_id), ADD CONSTRAINT cartodb_id_integer CHECK (cartodb_id::integer >=0);
DROP TABLE
SELECT 1
ERROR: CDB(_CDB_Has_Usable_Primary_ID: Error: invalid cartodb_id, cartodb_id): ALTER TABLE t ADD CONSTRAINT cartodb_id_pk PRIMARY KEY (cartodb_id), ADD CONSTRAINT cartodb_id_integer CHECK (cartodb_id::integer >=0);
DROP TABLE
SELECT 1
unsequenced cartodb_id cartodbfied fine
@@ -77,30 +92,30 @@ Table with both the_geom and wkb_geometry #141 cartodbfied fine
DROP TABLE
CREATE TABLE
INSERT 0 1
Many colliding columns #141 cartodbfied fine
ERROR: CDB(_CDB_Has_Usable_Primary_ID: multiple primary keys for table "many_colliding_columns" are not allowed): ALTER TABLE many_colliding_columns ADD CONSTRAINT cartodb_id_pk PRIMARY KEY (cartodb_id), ADD CONSTRAINT cartodb_id_integer CHECK (cartodb_id::integer >=0);
DROP TABLE
CREATE TABLE
INSERT 0 4
Table with null cartodb_id #148 cartodbfied fine
1|1
2|2
3|
4|3
ERROR: CDB(_CDB_Has_Usable_Primary_ID: Error: invalid cartodb_id, cartodb_id): ALTER TABLE test ADD CONSTRAINT cartodb_id_pk PRIMARY KEY (cartodb_id), ADD CONSTRAINT cartodb_id_integer CHECK (cartodb_id::integer >=0);
1
2
3
DROP TABLE
CREATE TABLE
INSERT 0 3
Table with non unique cartodb_id #148 cartodbfied fine
1|1
2|2
3|2
ERROR: CDB(_CDB_Has_Usable_Primary_ID: Error: invalid cartodb_id, cartodb_id): ALTER TABLE test ADD CONSTRAINT cartodb_id_pk PRIMARY KEY (cartodb_id), ADD CONSTRAINT cartodb_id_integer CHECK (cartodb_id::integer >=0);
1
2
2
DROP TABLE
CREATE TABLE
INSERT 0 4
Table with non unique and null cartodb_id #148 cartodbfied fine
1|1
2|2
3|
4|2
ERROR: CDB(_CDB_Has_Usable_Primary_ID: Error: invalid cartodb_id, cartodb_id): ALTER TABLE test ADD CONSTRAINT cartodb_id_pk PRIMARY KEY (cartodb_id), ADD CONSTRAINT cartodb_id_integer CHECK (cartodb_id::integer >=0);
1
2
2
DROP TABLE
CREATE TABLE
CREATE INDEX
@@ -132,5 +147,11 @@ NOTICE: Trying to recover data from _cartodb_id0 column
DROP TABLE
SET
BEGIN
DO
ROLLBACK
CREATE TABLE
Long table name could cause sequence collision while renaming #325 cartodbfied fine
DROP TABLE
DROP FUNCTION
DROP FUNCTION

View File

@@ -1,5 +1,6 @@
BEGIN
CREATE TABLE
COPY 3
none||
only_com_dec|.|,
only_dot_dec|,|.

View File

@@ -2,4 +2,10 @@ WITH data AS (
SELECT array_agg(x::numeric) s FROM generate_series(1,300) x
WHERE x % 5 != 0 AND x % 7 != 0
)
SELECT round(unnest(CDB_EqualIntervalBins(s, 7)),7) FROM data
SELECT round(unnest(CDB_EqualIntervalBins(s, 7)),7) FROM data;
WITH data_nulls AS (
SELECT array_agg(CASE WHEN x % 2 != 0 THEN x ELSE NULL END::numeric) s FROM generate_series(1,100) x
WHERE x % 5 != 0 AND x % 7 != 0
)
SELECT round(unnest(CDB_EqualIntervalBins(s, 7)),7) FROM data_nulls;

View File

@@ -5,3 +5,10 @@
213.8571429
256.4285714
299.0000000
15.0000000
29.0000000
43.0000000
57.0000000
71.0000000
85.0000000
99.0000000

View File

@@ -0,0 +1,10 @@
SET client_min_messages TO error;
\set VERBOSITY terse
CREATE TABLE tmptab1(id INT);
INSERT INTO tmptab1(id) VALUES (1), (2), (3);
CREATE TABLE tmptab2(id INT, value NUMERIC);
INSERT INTO tmptab2(id, value) VALUES (1, 10.0), (2, 20.0);
SELECT CDB_EstimateRowCount('SELECT SUM(value) FROM tmptab1 INNER JOIN tmptab2 ON (tmptab1.id = tmptab2.id);') AS row_count;
SELECT CDB_EstimateRowCount('UPDATE tmptab2 SET value = 30 WHERE id=2;') AS row_count;
DROP TABLE tmptab2;
DROP TABLE tmptab1;

View File

@@ -0,0 +1,9 @@
SET
CREATE TABLE
INSERT 0 3
CREATE TABLE
INSERT 0 2
1
1
DROP TABLE
DROP TABLE

View File

@@ -1,5 +1,11 @@
WITH data AS (
SELECT array_agg(x) x FROM generate_series(1,100) x
SELECT array_agg(x::numeric) s FROM generate_series(1,100) x
WHERE x % 5 != 0 AND x % 7 != 0
)
SELECT round(unnest(CDB_HeadsTailsBins(x, 7)),2) FROM data
)
SELECT round(unnest(CDB_HeadsTailsBins(s, 7)),2) FROM data;
WITH data_nulls AS (
SELECT array_agg(CASE WHEN x % 2 != 0 THEN x ELSE NULL END::numeric) s FROM generate_series(1,100) x
WHERE x % 5 != 0 AND x % 7 != 0
)
SELECT round(unnest(CDB_HeadsTailsBins(s, 7)),2) FROM data_nulls;

View File

@@ -5,3 +5,9 @@
96.50
98.00
99.00
49.76
74.65
88.50
94.50
98.00
99.00

View File

@@ -14,17 +14,17 @@ SELECT * FROM cartodb._CDB_Unique_Identifier(NULL, 'largolargolargolargolargolar
SELECT * FROM cartodb._CDB_Unique_Identifier('prefix_', 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL);
-- Test new identifier is found when name is taken from previous case
CREATE TABLE prefix_largolargolargolargolargolargolargolargolargolargolar (name text);
CREATE TABLE prefix_largolargolargolargolargolargolargolargolargolargola (name text);
SELECT * FROM cartodb._CDB_Unique_Identifier('prefix_', 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL);
DROP TABLE prefix_largolargolargolargolargolargolargolargolargolargolar;
DROP TABLE prefix_largolargolargolargolargolargolargolargolargolargola;
-- Test unique identifier creation with suffix with long length normal relname
SELECT * FROM cartodb._CDB_Unique_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', '_suffix');
-- Test new identifier is found when name is taken from previous case
CREATE TABLE largolargolargolargolargolargolargolargolargolargolar_suffix (name text);
CREATE TABLE largolargolargolargolargolargolargolargolargolargola_suffix (name text);
SELECT * FROM cartodb._CDB_Unique_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', '_suffix');
DROP TABLE largolargolargolargolargolargolargolargolargolargolar_suffix;
DROP TABLE largolargolargolargolargolargolargolargolargolargola_suffix;
-- Test unique identifier creation with normal length UTF8 relname
SELECT * FROM cartodb._CDB_Unique_Identifier(NULL, 'piraña', NULL);
@@ -72,7 +72,7 @@ SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'largolargolargol
DROP TABLE test;
-- Test new identifier is found when name is taken from previous case
CREATE TABLE test (prefix_largolargolargolargolargolargolargolargolargolargolar text);
CREATE TABLE test (prefix_largolargolargolargolargolargolargolargolargolargola text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL, 'test'::regclass);
DROP TABLE test;
@@ -82,7 +82,7 @@ SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargol
DROP TABLE test;
-- Test new identifier is found when name is taken from previous case
CREATE TABLE test (largolargolargolargolargolargolargolargolargolargolar_suffix text);
CREATE TABLE test (largolargolargolargolargolargolargolargolargolargola_suffix text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', '_suffix', 'test'::regclass);
DROP TABLE test;

View File

@@ -1,58 +1,58 @@
relname
prefix_relname
relname_suffix
largolargolargolargolargolargolargolargolargolargolargolargo
prefix_largolargolargolargolargolargolargolargolargolargolar
largolargolargolargolargolargolargolargolargolargolargolarg
prefix_largolargolargolargolargolargolargolargolargolargola
CREATE TABLE
prefix_largolargolargolargolargolargolargolargolargolargolar_0
prefix_largolargolargolargolargolargolargolargolargolargola0
DROP TABLE
largolargolargolargolargolargolargolargolargolargolar_suffix
largolargolargolargolargolargolargolargolargolargola_suffix
CREATE TABLE
largolargolargolargolargolargolargolargolargolargolar_suffix_0
largolargolargolargolargolargolargolargolargolargola_suffix0
DROP TABLE
piraña
prefix_piraña
piraña_suffix
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácid
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaáci
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi
CREATE TABLE
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_0
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi0
DROP TABLE
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix
CREATE TABLE
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix_0
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix0
DROP TABLE
CREATE TABLE
colname
prefix_colname
colname_suffix
largolargolargolargolargolargolargolargolargolargolargolargo
prefix_largolargolargolargolargolargolargolargolargolargolar
largolargolargolargolargolargolargolargolargolargolargolarg
prefix_largolargolargolargolargolargolargolargolargolargola
DROP TABLE
CREATE TABLE
prefix_largolargolargolargolargolargolargolargolargolargolar_0
prefix_largolargolargolargolargolargolargolargolargolargola0
DROP TABLE
CREATE TABLE
largolargolargolargolargolargolargolargolargolargolar_suffix
largolargolargolargolargolargolargolargolargolargola_suffix
DROP TABLE
CREATE TABLE
largolargolargolargolargolargolargolargolargolargolar_suffix_0
largolargolargolargolargolargolargolargolargolargola_suffix0
DROP TABLE
CREATE TABLE
piraña
prefix_piraña
piraña_suffix
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácid
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaáci
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi
DROP TABLE
CREATE TABLE
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_0
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi0
DROP TABLE
CREATE TABLE
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix
DROP TABLE
CREATE TABLE
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix_0
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix0
DROP TABLE
pira
pirañ

View File

@@ -1,3 +1,6 @@
set client_min_messages to error;
\set VERBOSITY TERSE
-- Check correctness of an hexagons grid
--
-- Cells must have no overlaps and have a number of
@@ -45,3 +48,9 @@ WITH
0.002 as radius ),
grid AS ( SELECT CDB_HexagonGrid(env, radius) AS cell from params)
SELECT '#160', count(cell) > 23000 from grid;
-- Check small grids are generated...
SELECT COUNT(*) FROM cartodb.CDB_HexagonGrid(ST_MakeEnvelope(0,0,1000,1000,3857), 10);
-- But large grids produce an error
SELECT COUNT(*) FROM cartodb.CDB_HexagonGrid(ST_MakeEnvelope(0,0,1000,1000,3857), 1);

View File

@@ -1,2 +1,5 @@
SET
9|63|count / npoints
#160|t
3886
ERROR: The requested grid is too big to be rendered

View File

@@ -1,5 +1,23 @@
WITH data AS (
SELECT array_agg(x) x FROM generate_series(1,100) x
WHERE x % 5 != 0 AND x % 7 != 0
)
SELECT unnest(CDB_JenksBins(x, 7)) FROM data
SELECT Array[0.99, 1.0, 1.01,
4.99, 5.01,
10.01, 10.01,
15.01, 14.99,
20.1, 19.9]::numeric[] AS s
)
-- expectation is: 1, 5, 10, 15, 20
-- TODO: fix cdb_jenksbins to match ^^
SELECT round(unnest(CDB_JenksBins(s, 5))) FROM data;
WITH data_nulls AS (
SELECT Array[0.99, 1.0, 1.01,
4.99, 5.01,
null, null,
10.01, 10.01,
15.01, 14.99,
null, null,
20.1, 19.9]::numeric[] AS s
)
-- expectation is: 1, 5, 10, 15, 20
-- TODO: fix cdb_jenksbins to match ^^
SELECT round(unnest(CDB_JenksBins(s, 5))) FROM data_nulls;

View File

@@ -1,7 +1,10 @@
13
29
43
57
71
83
99
1
5
10
20
20
1
5
10
20

View File

@@ -0,0 +1,43 @@
SET client_min_messages TO error;
\set VERBOSITY default
\i test/overviews/fixtures.sql
SELECT _CDB_Aggregable_Attributes_Expression('base_bare_t'::regclass);
SELECT _CDB_Aggregated_Attributes_Expression('base_bare_t'::regclass);
SELECT _CDB_Aggregated_Attributes_Expression('base_bare_t'::regclass, 'tab');
SELECT CDB_CreateOverviews('base_bare_t'::regclass);
SELECT count(*) FROM _vovw_2_base_bare_t;
SELECT _CDB_Aggregable_Attributes_Expression('base_t'::regclass);
SELECT _CDB_Aggregated_Attributes_Expression('base_t'::regclass);
SELECT _CDB_Aggregated_Attributes_Expression('base_t'::regclass, 'tab');
SELECT CDB_CreateOverviews('base_t'::regclass);
SELECT count(*) FROM _vovw_2_base_t;
SELECT CDB_CreateOverviews('polyg_t'::regclass);
SELECT CDB_CreateOverviews('column_types_t'::regclass);
SELECT CDB_Overviews('base_t'::regclass);
SELECT CDB_Overviews('"public"."base_t"'::regclass);
SELECT CDB_Overviews(ARRAY['base_t'::regclass, 'base_bare_t'::regclass]);
SELECT CDB_Overviews('polyg_t'::regclass);
SELECT CDB_Overviews('column_types_t'::regclass);
SELECT CDB_DropOverviews('column_types_t'::regclass);
SELECT CDB_DropOverviews('base_bare_t'::regclass);
SELECT CDB_DropOverviews('base_t'::regclass);
SELECT count(*) FROM _vovw_2_base_t;
SELECT CDB_CreateOverviewsWithToleranceInPixels('base_t'::regclass, 7.5);
SELECT count(*) FROM _vovw_2_base_t;
SELECT CDB_DropOverviews('base_t'::regclass);
DROP TABLE column_types_t;
DROP TABLE base_bare_t;
DROP TABLE base_t;
DROP TABLE polyg_t;

View File

@@ -0,0 +1,48 @@
SET
CREATE TABLE
INSERT 0 1114
CREATE TABLE
INSERT 0 1114
CREATE TABLE
INSERT 0 5
SELECT 1114
{_vovw_2_base_bare_t,_vovw_1_base_bare_t,_vovw_0_base_bare_t}
126
number,int_number,name,start
SUM(number*1)/count(*)::double precision AS number,SUM(int_number*1)/count(*)::integer AS int_number,CASE WHEN count(distinct name) = 1 THEN MIN(name) WHEN count(*) < 5 THEN string_agg(distinct name,' / ') ELSE '*' END::text AS name,CASE count(*) WHEN 1 THEN MIN(start) ELSE NULL END::date AS start
SUM(tab.number*1)/count(*)::double precision AS number,SUM(tab.int_number*1)/count(*)::integer AS int_number,CASE WHEN count(distinct tab.name) = 1 THEN MIN(tab.name) WHEN count(*) < 5 THEN string_agg(distinct tab.name,' / ') ELSE '*' END::text AS name,CASE count(*) WHEN 1 THEN MIN(tab.start) ELSE NULL END::date AS start
{_vovw_2_base_t,_vovw_1_base_t,_vovw_0_base_t}
126
{_vovw_2_column_types_t,_vovw_1_column_types_t,_vovw_0_column_types_t}
(base_t,0,_vovw_0_base_t)
(base_t,1,_vovw_1_base_t)
(base_t,2,_vovw_2_base_t)
(base_t,0,_vovw_0_base_t)
(base_t,1,_vovw_1_base_t)
(base_t,2,_vovw_2_base_t)
(base_bare_t,0,_vovw_0_base_bare_t)
(base_bare_t,1,_vovw_1_base_bare_t)
(base_bare_t,2,_vovw_2_base_bare_t)
(base_t,0,_vovw_0_base_t)
(base_t,1,_vovw_1_base_t)
(base_t,2,_vovw_2_base_t)
(column_types_t,0,_vovw_0_column_types_t)
(column_types_t,1,_vovw_1_column_types_t)
(column_types_t,2,_vovw_2_column_types_t)
ERROR: relation "_vovw_2_base_t" does not exist
LINE 1: SELECT count(*) FROM _vovw_2_base_t;
^
{_vovw_5_base_t,_vovw_4_base_t,_vovw_3_base_t,_vovw_2_base_t,_vovw_1_base_t,_vovw_0_base_t}
38
DROP TABLE
DROP TABLE
DROP TABLE
DROP TABLE

View File

@@ -1,5 +1,17 @@
WITH data AS (
SELECT array_agg(x) x FROM generate_series(1,100) x
WHERE x % 5 != 0 AND x % 7 != 0
SELECT array_agg(x::numeric) AS s
FROM generate_series(0, 99) AS x
)
SELECT unnest(CDB_QuantileBins(x, 7)) FROM data
SELECT unnest(CDB_QuantileBins(s, 10))
FROM data;
WITH data_nulls AS (
SELECT array_agg(x::numeric) AS s
FROM (
SELECT x FROM generate_series(0, 99) AS x
UNION ALL
SELECT null AS x FROM generate_series(1, 10) AS x
) _wrap
)
SELECT unnest(CDB_QuantileBins(s, 10))
FROM data_nulls;

View File

@@ -1,7 +1,20 @@
13
9
19
29
43
57
71
86
39
49
59
69
79
89
99
9
19
29
39
49
59
69
79
89
99

View File

@@ -1,3 +1,6 @@
SET client_min_messages TO error;
\set VERBOSITY terse
WITH q AS ( SELECT CDB_QueryStatements('
SELECT * FROM geometry_columns;
') as statement )

View File

@@ -1,3 +1,4 @@
SET
1|1|SELECT * FROM geometry_columns
2|1|SELECT * FROM geometry_columns
3|1|SELECT * FROM geometry_columns

View File

@@ -1,3 +1,5 @@
SET client_min_messages TO warning;
\set VERBOSITY terse
WITH inp AS ( select 'SELECT * FROM geometry_columns'::text as q )
SELECT q, CDB_QueryTables(q) from inp;

View File

@@ -1,17 +1,14 @@
SELECT * FROM geometry_columns|{pg_catalog.pg_attribute,pg_catalog.pg_class,pg_catalog.pg_namespace,pg_catalog.pg_type}
SET
SELECT * FROM geometry_columns|{pg_catalog.pg_attribute,pg_catalog.pg_class,pg_catalog.pg_constraint,pg_catalog.pg_namespace,pg_catalog.pg_type}
SELECT a.attname FROM pg_class c JOIN pg_attribute a on (a.attrelid = c.oid)|{pg_catalog.pg_attribute,pg_catalog.pg_class}
CREATE table "my'tab;le" as select 1|{}
SELECT a.oid, b.oid FROM pg_class a, pg_class b|{pg_catalog.pg_class}
SELECT 1 as col1; select 2 as col2|{}
WARNING: CDB_QueryTables cannot explain query: select 1 from nonexistant (42P01: relation "nonexistant" does not exist)
CONTEXT: PL/pgSQL function cdb_querytables(text) line 3 at RETURN
ERROR: relation "nonexistant" does not exist
CONTEXT: PL/pgSQL function cdb_querytables(text) line 3 at RETURN
begin; select * from pg_class; commit;|{pg_catalog.pg_class}
WARNING: CDB_QueryTables cannot explain query: select * from test (42P01: relation "test" does not exist)
CONTEXT: PL/pgSQL function cdb_querytables(text) line 3 at RETURN
ERROR: relation "test" does not exist
CONTEXT: PL/pgSQL function cdb_querytables(text) line 3 at RETURN
WITH a AS (select * from pg_class) select * from a|{pg_catalog.pg_class}
CREATE SCHEMA
CREATE TABLE
@@ -20,4 +17,4 @@ select * from sc.test|{sc.test}
DROP TABLE
DROP SCHEMA
SELECT
* FROM geometry_columns|{pg_catalog.pg_attribute,pg_catalog.pg_class,pg_catalog.pg_namespace,pg_catalog.pg_type}
* FROM geometry_columns|{pg_catalog.pg_attribute,pg_catalog.pg_class,pg_catalog.pg_constraint,pg_catalog.pg_namespace,pg_catalog.pg_type}

View File

@@ -1,5 +1,5 @@
set client_min_messages to error;
\set VERBOSITY default
\set VERBOSITY TERSE
-- See the dice
SELECT setseed(0.5);
@@ -27,5 +27,21 @@ INSERT INTO big VALUES (8193);
SELECT CDB_SetUserQuotaInBytes(0);
INSERT INTO big VALUES (8194);
DROP TABLE big;
--analysis tables should be excluded from quota:
CREATE TABLE big(a int);
CREATE TRIGGER test_quota BEFORE UPDATE OR INSERT ON big
EXECUTE PROCEDURE CDB_CheckQuota(1, 1, 'public');
SELECT CDB_SetUserQuotaInBytes(1);
CREATE TABLE analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d4(id int);
INSERT INTO analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d4(id) VALUES (1),(2),(3),(4),(5);
INSERT INTO big VALUES (1); -- allowed, check runs before
DROP TABLE analysis_2f13a3dbd7_41bd92976fc6dd97072afe4ee450054f4c0715d4;
INSERT INTO big VALUES (2); -- disallowed, quota exceeds before
DROP TABLE big;
SELECT CDB_SetUserQuotaInBytes(0);
set client_min_messages to NOTICE;
DROP FUNCTION _CDB_UserQuotaInBytes();

View File

@@ -18,5 +18,15 @@ ERROR: Quota exceeded by 443.998046875KB
0
INSERT 0 1
DROP TABLE
CREATE TABLE
CREATE TRIGGER
1
CREATE TABLE
INSERT 0 5
INSERT 0 1
DROP TABLE
ERROR: Quota exceeded by 3.9990234375KB
DROP TABLE
0
SET
DROP FUNCTION

View File

@@ -0,0 +1,8 @@
set client_min_messages to error;
\set VERBOSITY TERSE
-- Check small grids are generated...
SELECT COUNT(*) FROM cartodb.CDB_RectangleGrid(ST_MakeEnvelope(0,0,1000,1000,3857), 10, 10);
-- But large grids produce an error
SELECT COUNT(*) FROM cartodb.CDB_RectangleGrid(ST_MakeEnvelope(0,0,1000,1000,3857), 1, 1);

View File

@@ -0,0 +1,3 @@
SET
10000
ERROR: The requested grid is too big to be rendered

View File

@@ -4,6 +4,6 @@ range AS ( select z, generate_series(0, pow(2,z)::int-1) as r FROM zoom),
inp AS ( select z0.z, r1.r as x, r2.r as y FROM zoom z0, range r1, range r2 WHERE z0.z = r1.z and r1.z = r2.z ),
ext AS ( select x,y,z,CDB_XYZ_Extent(x,y,z) as g from inp )
select X::text || ',' || Y::text || ',' || Z::text as xyz,
st_xmin(g), st_xmax(g), st_ymin(g), st_ymax(g)
round(st_xmin(g)), round(st_xmax(g)), round(st_ymin(g)), round(st_ymax(g))
from ext order by xyz;

View File

@@ -1,21 +1,21 @@
0,0,0|-20037508.5|20037508.5|-20037508.5|20037508.5
0,0,1|-20037508.5|0|0|20037508.5
0,0,2|-20037508.5|-10018754.25|10018754.25|20037508.5
0,1,1|-20037508.5|0|-20037508.5|0
0,1,2|-20037508.5|-10018754.25|0|10018754.25
0,2,2|-20037508.5|-10018754.25|-10018754.25|0
0,3,2|-20037508.5|-10018754.25|-20037508.5|-10018754.25
1,0,1|0|20037508.5|0|20037508.5
1,0,2|-10018754.25|0|10018754.25|20037508.5
1,1,1|0|20037508.5|-20037508.5|0
1,1,2|-10018754.25|0|0|10018754.25
1,2,2|-10018754.25|0|-10018754.25|0
1,3,2|-10018754.25|0|-20037508.5|-10018754.25
2,0,2|0|10018754.25|10018754.25|20037508.5
2,1,2|0|10018754.25|0|10018754.25
2,2,2|0|10018754.25|-10018754.25|0
2,3,2|0|10018754.25|-20037508.5|-10018754.25
3,0,2|10018754.25|20037508.5|10018754.25|20037508.5
3,1,2|10018754.25|20037508.5|0|10018754.25
3,2,2|10018754.25|20037508.5|-10018754.25|0
3,3,2|10018754.25|20037508.5|-20037508.5|-10018754.25
0,0,0|-20037508|20037508|-20037508|20037508
0,0,1|-20037508|0|0|20037508
0,0,2|-20037508|-10018754|10018754|20037508
0,1,1|-20037508|0|-20037508|0
0,1,2|-20037508|-10018754|0|10018754
0,2,2|-20037508|-10018754|-10018754|0
0,3,2|-20037508|-10018754|-20037508|-10018754
1,0,1|0|20037508|0|20037508
1,0,2|-10018754|0|10018754|20037508
1,1,1|0|20037508|-20037508|0
1,1,2|-10018754|0|0|10018754
1,2,2|-10018754|0|-10018754|0
1,3,2|-10018754|0|-20037508|-10018754
2,0,2|0|10018754|10018754|20037508
2,1,2|0|10018754|0|10018754
2,2,2|0|10018754|-10018754|0
2,3,2|0|10018754|-20037508|-10018754
3,0,2|10018754|20037508|10018754|20037508
3,1,2|10018754|20037508|0|10018754
3,2,2|10018754|20037508|-10018754|0
3,3,2|10018754|20037508|-20037508|-10018754

View File

@@ -1,6 +0,0 @@
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

@@ -12,6 +12,8 @@
DATABASE=test_extension
CMD='echo psql'
CMD=psql
SED=sed
PG_PARALLEL=$(pg_config --version | awk '{$2*=1000; if ($2 >= 9600) print 1; else print 0;}' 2> /dev/null || echo 0)
OK=0
PARTIALOK=0
@@ -26,6 +28,30 @@ function clear_partial_result() {
PARTIALOK=0
}
function load_sql_file() {
if [[ $PG_PARALLEL -eq 0 ]]
then
tmp_file=/tmp/$(basename $1)_no_parallel
${SED} $1 -e 's/PARALLEL \= [A-Z]*/''/g' -e 's/PARALLEL [A-Z]*/''/g' > $tmp_file
${CMD} -d ${DATABASE} -f $tmp_file
rm $tmp_file
else
${CMD} -d ${DATABASE} -f $1
fi
}
function load_sql_file_schema() {
if [[ $PG_PARALLEL -eq 0 ]]
then
tmp_file=/tmp/$(basename $1)_no_parallel
${SED} $1 -e 's/PARALLEL \= [A-Z]*/''/g' -e 's/PARALLEL [A-Z]*/''/g' > $tmp_file
PGOPTIONS="$PGOPTIONS --search_path=\"$2\"" ${CMD} -d ${DATABASE} -f $tmp_file
rm $tmp_file
else
PGOPTIONS="$PGOPTIONS --search_path=\"$2\"" ${CMD} -d ${DATABASE} -f $1
fi
}
function sql() {
local ROLE
@@ -172,8 +198,7 @@ function drop_raster_table() {
sql ${ROLE} "DROP TABLE ${ROLE}.${TABLENAME};"
}
function setup() {
function setup_database() {
${CMD} -c "CREATE DATABASE ${DATABASE}"
sql "CREATE SCHEMA cartodb;"
sql "GRANT USAGE ON SCHEMA cartodb TO public;"
@@ -181,10 +206,19 @@ function setup() {
sql "CREATE EXTENSION plpythonu;"
log_info "########################### BOOTSTRAP ###########################"
${CMD} -d ${DATABASE} -f scripts-available/CDB_Organizations.sql
# trick to allow forcing a schema when loading SQL files (see: http://bit.ly/1HeLnhL)
${CMD} -d ${DATABASE} -f test/extension/run_at_cartodb_schema.sql
load_sql_file scripts-available/CDB_Organizations.sql
load_sql_file scripts-available/CDB_OverviewsSupport.sql
load_sql_file scripts-available/CDB_AnalysisSupport.sql
load_sql_file_schema scripts-available/CDB_Quota.sql cartodb
load_sql_file_schema scripts-available/CDB_TableMetadata.sql cartodb
load_sql_file_schema scripts-available/CDB_ColumnNames.sql cartodb
load_sql_file_schema scripts-available/CDB_ColumnType.sql cartodb
load_sql_file_schema scripts-available/CDB_AnalysisCatalog.sql cartodb
}
function setup() {
setup_database
log_info "############################# SETUP #############################"
create_role_and_schema cdb_testmember_1
@@ -199,6 +233,10 @@ function setup() {
sql cdb_testmember_2 'SELECT * FROM cdb_testmember_2.bar;'
}
function tear_down_database() {
${CMD} -c "DROP DATABASE ${DATABASE}"
}
function tear_down() {
log_info "########################### USER TEAR DOWN ###########################"
sql cdb_testmember_1 "SELECT * FROM cartodb.CDB_Organization_Remove_Access_Permission('cdb_testmember_1', 'foo', 'cdb_testmember_2');"
@@ -219,9 +257,11 @@ function tear_down() {
sql 'DROP ROLE cdb_testmember_1;'
sql 'DROP ROLE cdb_testmember_2;'
${CMD} -c "DROP DATABASE ${DATABASE}"
tear_down_database
DATABASE=postgres sql postgres 'DROP ROLE IF EXISTS publicuser';
}
function run_tests() {
local FAILED_TESTS=()
@@ -343,6 +383,41 @@ function test_cdb_tablemetadatatouch_fails_from_user_without_permission() {
sql postgres "REVOKE ALL ON CDB_TableMetadata FROM cdb_testmember_1;"
}
function test_cdb_tablemetadatatouch_fully_qualifies_names() {
sql postgres "CREATE TABLE touch_invalidations (table_name text);"
sql postgres "create or replace function cartodb.cdb_invalidate_varnish(table_name text) returns void as \$\$ begin insert into touch_invalidations select table_name; end; \$\$ language 'plpgsql';"
#default schema
sql "CREATE TABLE touch_example (a int);"
sql postgres "SELECT CDB_TableMetadataTouch('touch_example');"
sql postgres "SELECT table_name FROM touch_invalidations" should "public.touch_example"
sql postgres "TRUNCATE TABLE touch_invalidations"
sql postgres "DROP TABLE touch_example"
#setup different schema
sql postgres "CREATE SCHEMA test_schema;"
sql postgres "CREATE TABLE test_schema.touch_example (a int);"
#different schema outside search_path
sql postgres "SELECT CDB_TableMetadataTouch('test_schema.touch_example');"
sql postgres "SELECT table_name FROM touch_invalidations" should "test_schema.touch_example"
sql postgres "TRUNCATE TABLE touch_invalidations"
#different schema in default search_path
sql postgres "SET search_path=test_schema,public,cartodb; SELECT CDB_TableMetadataTouch('test_schema.touch_example');"
sql postgres "SELECT table_name FROM touch_invalidations" should "test_schema.touch_example"
sql postgres "TRUNCATE TABLE touch_invalidations"
#teardown different schema
sql postgres 'DROP TABLE test_schema.touch_example;'
sql postgres 'DROP SCHEMA test_schema;'
sql postgres 'DROP FUNCTION cartodb.cdb_invalidate_varnish(table_name text);'
sql postgres 'DROP TABLE touch_invalidations'
}
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);'
@@ -378,8 +453,8 @@ function test_cdb_column_type() {
}
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
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file 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);'
@@ -394,8 +469,8 @@ function test_cdb_querytables_schema_and_table_names_with_dots() {
}
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
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file scripts-available/CDB_QueryTables.sql
sql postgres 'CREATE TABLE "w.a.d.u.s" (a int);';
@@ -406,8 +481,8 @@ function test_cdb_querytables_table_name_with_dots() {
}
function test_cdb_querytables_happy_cases() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file scripts-available/CDB_QueryTables.sql
sql postgres 'CREATE TABLE wadus (a int);';
sql postgres 'CREATE TABLE "FOOBAR" (a int);';
@@ -429,6 +504,117 @@ function test_cdb_querytables_happy_cases() {
sql postgres 'DROP SCHEMA foo;'
}
function test_foreign_tables() {
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file scripts-available/CDB_QueryTables.sql
load_sql_file scripts-available/CDB_TableMetadata.sql
load_sql_file scripts-available/CDB_Conf.sql
load_sql_file scripts-available/CDB_ForeignTable.sql
DATABASE=fdw_target setup_database
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file scripts-available/CDB_QueryTables.sql
load_sql_file scripts-available/CDB_TableMetadata.sql
DATABASE=fdw_target sql postgres "DO
\$\$
BEGIN
IF NOT EXISTS (
SELECT *
FROM pg_catalog.pg_user
WHERE usename = 'publicuser') THEN
CREATE ROLE publicuser LOGIN;
END IF;
END
\$\$;"
DATABASE=fdw_target sql postgres 'CREATE SCHEMA test_fdw;'
DATABASE=fdw_target sql postgres 'CREATE TABLE test_fdw.foo (a int);'
DATABASE=fdw_target sql postgres 'INSERT INTO test_fdw.foo (a) values (42);'
DATABASE=fdw_target sql postgres 'CREATE TABLE test_fdw.foo2 (a int);'
DATABASE=fdw_target sql postgres 'INSERT INTO test_fdw.foo2 (a) values (42);'
DATABASE=fdw_target sql postgres "CREATE USER fdw_user WITH PASSWORD 'foobarino';"
DATABASE=fdw_target sql postgres 'GRANT USAGE ON SCHEMA test_fdw TO fdw_user;'
DATABASE=fdw_target sql postgres 'GRANT SELECT ON TABLE test_fdw.foo TO fdw_user;'
DATABASE=fdw_target sql postgres 'GRANT SELECT ON TABLE test_fdw.foo2 TO fdw_user;'
DATABASE=fdw_target sql postgres 'GRANT SELECT ON cdb_tablemetadata_text TO fdw_user;'
DATABASE=fdw_target sql postgres "SELECT cdb_tablemetadatatouch('test_fdw.foo'::regclass);"
DATABASE=fdw_target sql postgres "SELECT cdb_tablemetadatatouch('test_fdw.foo2'::regclass);"
sql postgres "SELECT cartodb.CDB_Conf_SetConf('fdws', '{\"test_fdw\": {\"server\": {\"host\": \"localhost\", \"dbname\": \"fdw_target\"},
\"users\": {\"public\": {\"user\": \"fdw_user\", \"password\": \"foobarino\"}}}}')"
sql postgres "SELECT cartodb._CDB_Setup_FDW('test_fdw')"
sql postgres "SHOW server_version_num"
if [ "$RESULT" -gt 90499 ]
then
sql postgres "SELECT cartodb.CDB_Add_Remote_Table('test_fdw', 'foo')"
sql postgres "SELECT * from test_fdw.foo;"
else
echo "NOTICE: PostgreSQL version is less than 9.5 ($RESULT). Skipping CDB_Add_Remote_Table."
sql postgres "CREATE FOREIGN TABLE test_fdw.foo (a int) SERVER test_fdw OPTIONS (table_name 'foo', schema_name 'test_fdw')"
fi
sql postgres "SELECT n.nspname,
c.relname,
s.srvname FROM pg_catalog.pg_foreign_table ft
INNER JOIN pg_catalog.pg_class c ON c.oid = ft.ftrelid
INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
INNER JOIN pg_catalog.pg_foreign_server s ON s.oid = ft.ftserver
ORDER BY 1, 2" should "test_fdw|cdb_tablemetadata|test_fdw
test_fdw|foo|test_fdw"
sql postgres "SELECT cartodb.CDB_Get_Foreign_Updated_At('test_fdw.foo'::regclass) < NOW()" should 't'
sql postgres "SELECT a from test_fdw.foo LIMIT 1;" should 42
# Check function CDB_QueryTables_Updated_At
sql postgres 'CREATE TABLE local (b int);'
sql postgres 'INSERT INTO local (b) VALUES (43);'
sql postgres "SELECT cdb_tablemetadatatouch('public.local'::regclass);"
local query='$query$ SELECT * FROM test_fdw.foo, local $query$::text'
sql postgres "SELECT dbname, schema_name, table_name FROM cartodb.CDB_QueryTables_Updated_At(${query}) ORDER BY dbname;" should 'fdw_target|test_fdw|foo
test_extension|public|local'
sql postgres "SELECT table_name FROM cartodb.CDB_QueryTables_Updated_At(${query}) order by updated_at;" should 'foo
local'
# Check function CDB_Last_Updated_Time
sql postgres "SELECT cartodb.CDB_Last_Updated_Time('{test_fdw.foo,public.local}'::text[]) < now()" should 't'
sql postgres "SELECT cartodb.CDB_Last_Updated_Time('{test_fdw.foo,public.local}'::text[]) > (now() - interval '1 minute')" should 't'
# Check we quote names on output as needed (as CDB_QueryTablesText does)
sql postgres 'CREATE TABLE "local-table-with-dashes" (c int)';
sql postgres 'INSERT INTO "local-table-with-dashes" (c) VALUES (44)';
sql postgres "SELECT cdb_tablemetadatatouch('public.local-table-with-dashes'::regclass);"
query='$query$ SELECT * FROM test_fdw.foo, local, public."local-table-with-dashes" $query$::text'
sql postgres "SELECT dbname, schema_name, table_name FROM cartodb.CDB_QueryTables_Updated_At(${query}) ORDER BY dbname, schema_name, table_name;" should 'fdw_target|test_fdw|foo
test_extension|public|local
test_extension|public|"local-table-with-dashes"'
# Check CDB_Last_Updated_Time supports quoted identifiers
sql postgres "SELECT cartodb.CDB_Last_Updated_Time(ARRAY['test_extension.public.\"local-table-with-dashes\"']::text[]) < now()" should 't'
sql postgres "SELECT cartodb.CDB_Last_Updated_Time(ARRAY['test_extension.public.\"local-table-with-dashes\"']::text[]) > (now() - interval '1 minute')" should 't'
DATABASE=fdw_target sql postgres 'REVOKE USAGE ON SCHEMA test_fdw FROM fdw_user;'
DATABASE=fdw_target sql postgres 'REVOKE SELECT ON test_fdw.foo FROM fdw_user;'
DATABASE=fdw_target sql postgres 'REVOKE SELECT ON test_fdw.foo2 FROM fdw_user;'
DATABASE=fdw_target sql postgres 'REVOKE SELECT ON cdb_tablemetadata_text FROM fdw_user;'
DATABASE=fdw_target sql postgres 'DROP ROLE fdw_user;'
sql postgres "select pg_terminate_backend(pid) from pg_stat_activity where datname='fdw_target';"
DATABASE=fdw_target tear_down_database
}
function test_cdb_catalog_basic_node() {
DEF="'{\"type\":\"buffer\",\"source\":\"b2db66bc7ac02e135fd20bbfef0fdd81b2d15fad\",\"radio\":10000}'"
sql postgres "INSERT INTO cartodb.cdb_analysis_catalog (node_id, analysis_def) VALUES ('1bbc4c41ea7c9d3a7dc1509727f698b7', ${DEF}::json)"
sql postgres "SELECT status from cartodb.cdb_analysis_catalog where node_id = '1bbc4c41ea7c9d3a7dc1509727f698b7'" should 'pending'
sql postgres "DELETE FROM cartodb.cdb_analysis_catalog"
}
#################################################### TESTS END HERE ####################################################
run_tests $@

View File

@@ -8,8 +8,9 @@
#
DATABASE=test_organizations
CMD='echo psql'
CMD=psql
SED=sed
PG_PARALLEL=$(pg_config --version | awk '{$2*=1000; if ($2 >= 9600) print 1; else print 0;}' 2> /dev/null || echo 0)
OK=0
PARTIALOK=0
@@ -24,6 +25,18 @@ function clear_partial_result() {
PARTIALOK=0
}
function load_sql_file() {
if [[ $PG_PARALLEL -eq 0 ]]
then
tmp_file=/tmp/$(basename $1)_no_parallel
${SED} $1 -e 's/PARALLEL \= [A-Z]*/''/g' -e 's/PARALLEL [A-Z]*/''/g' > $tmp_file
${CMD} -d ${DATABASE} -f $tmp_file
rm $tmp_file
else
${CMD} -d ${DATABASE} -f $1
fi
}
function sql() {
local ROLE
@@ -163,10 +176,10 @@ function setup() {
sql "GRANT USAGE ON SCHEMA cartodb TO public;"
log_info "########################### BOOTSTRAP ###########################"
${CMD} -d ${DATABASE} -f scripts-available/CDB_Organizations.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_Conf.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_Groups.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_Groups_API.sql
load_sql_file scripts-available/CDB_Organizations.sql
load_sql_file scripts-available/CDB_Conf.sql
load_sql_file scripts-available/CDB_Groups.sql
load_sql_file scripts-available/CDB_Groups_API.sql
log_info "############################# SETUP #############################"
create_role_and_schema cdb_org_admin
@@ -302,6 +315,8 @@ function test_member_1_cannot_grant_read_write_permission_to_other_schema_than_i
}
function test_member_2_can_write_to_member_1_table_after_write_permission_is_added() {
sql cdb_testmember_1 "ALTER TABLE cdb_testmember_1.foo ADD cartodb_id SERIAL NOT NULL UNIQUE;"
sql cdb_testmember_1 "SELECT * FROM cartodb.CDB_Organization_Add_Table_Read_Write_Permission('cdb_testmember_1', 'foo', 'cdb_testmember_2')"
sql cdb_testmember_2 'INSERT INTO cdb_testmember_1.foo VALUES (5), (6), (7), (8), (9);'
sql cdb_testmember_1 'SELECT count(*) FROM cdb_testmember_1.foo;' should 10
@@ -309,6 +324,8 @@ function test_member_2_can_write_to_member_1_table_after_write_permission_is_add
sql cdb_testmember_2 'DELETE FROM cdb_testmember_1.foo where a = 9;'
sql cdb_testmember_1 'SELECT count(*) FROM cdb_testmember_1.foo;' should 9
sql cdb_testmember_2 'SELECT count(*) FROM cdb_testmember_1.foo;' should 9
sql cdb_testmember_1 "ALTER TABLE cdb_testmember_1.foo DROP cartodb_id;"
}
function test_member_1_removes_access_and_member_2_can_no_longer_query_the_table() {
@@ -319,10 +336,14 @@ function test_member_1_removes_access_and_member_2_can_no_longer_query_the_table
}
function test_member_1_removes_access_and_member_2_can_no_longer_write_to_the_table() {
sql cdb_testmember_1 "ALTER TABLE cdb_testmember_1.foo ADD cartodb_id SERIAL NOT NULL UNIQUE;"
sql cdb_testmember_1 "SELECT * FROM cartodb.CDB_Organization_Add_Table_Read_Write_Permission('cdb_testmember_1', 'foo', 'cdb_testmember_2')"
sql cdb_testmember_2 'INSERT INTO cdb_testmember_1.foo VALUES (5), (6), (7), (8), (9);'
sql cdb_testmember_1 "SELECT * FROM cartodb.CDB_Organization_Remove_Access_Permission('cdb_testmember_1', 'foo', 'cdb_testmember_2')"
sql cdb_testmember_2 'INSERT INTO cdb_testmember_1.foo VALUES (5), (6), (7), (8), (9);' fails
sql cdb_testmember_1 "ALTER TABLE cdb_testmember_1.foo DROP cartodb_id;"
}
function test_giving_permissions_to_two_tables_and_removing_from_first_table_should_not_remove_from_second() {
@@ -380,20 +401,20 @@ function test_user_can_read_when_it_has_permission_after_organization_permission
}
function test_cdb_querytables_returns_schema_and_table_name() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file scripts-available/CDB_QueryTables.sql
sql cdb_testmember_1 "select * from CDB_QueryTables('select * from foo');" should "{cdb_testmember_1.foo}"
}
function test_cdb_querytables_returns_schema_and_table_name_for_several_schemas() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file scripts-available/CDB_QueryTables.sql
sql postgres "select * from CDB_QueryTables('select * from cdb_testmember_1.foo, cdb_testmember_2.bar');" should "{cdb_testmember_1.foo,cdb_testmember_2.bar}"
}
function test_cdb_querytables_does_not_return_functions_as_part_of_the_resultset() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
load_sql_file scripts-available/CDB_QueryStatements.sql
load_sql_file scripts-available/CDB_QueryTables.sql
sql postgres "select * from CDB_QueryTables('select * from cdb_testmember_1.foo, cdb_testmember_2.bar, plainto_tsquery(''foo'')');" should "{cdb_testmember_1.foo,cdb_testmember_2.bar}"
}
@@ -405,7 +426,7 @@ function test_cdb_usertables_should_work_with_orgusers() {
sql cdb_testmember_1 "CREATE TABLE test_perms_pub (a int)"
sql cdb_testmember_1 "INSERT INTO test_perms_pub (a) values (1);"
sql cdb_testmember_1 "GRANT SELECT ON TABLE test_perms_pub TO publicuser"
sql cdb_testmember_1 "CREATE TABLE test_perms_priv (a int)"
@@ -419,7 +440,7 @@ function test_cdb_usertables_should_work_with_orgusers() {
# test CDB_UserTables with publicuser
${CMD} -d ${DATABASE} -f scripts-available/CDB_UserTables.sql
load_sql_file scripts-available/CDB_UserTables.sql
sql publicuser "SELECT count(*) FROM CDB_UserTables('all')" should 1
sql publicuser "SELECT count(*) FROM CDB_UserTables('public')" should 1

Some files were not shown because too many files have changed in this diff Show More