diff --git a/docs/dev-guide.md b/docs/dev-guide.md index 4f9f0090b83..0986409f2e0 100644 --- a/docs/dev-guide.md +++ b/docs/dev-guide.md @@ -275,6 +275,33 @@ FROM ``` +## DB stored procedures (sprocs) + +* Stored procedures are created by the files in `sprocs/`. To call a stored procedure from JavaScript, use code like: + +``` +const workspace_id = 1342; +const message = 'Startup successful'; +sqldb.call('workspaces_message_update', [workspace_id, message], (err, result) => { + if (ERR(err, callback)) return; + // we could use the result here if we want the return value of the stored procedure + callback(null); +}); +``` + +* The stored procedures are all contained in a separate [database schema](https://www.postgresql.org/docs/12/ddl-schemas.html) with a name like `server_2021-07-07T20:25:04.779Z_T75V6Y`. To see a list of the schemas use the `\dn` command in `psql`. + +* To be able to use the stored procedures from the `psql` command line it is necessary to get the most recent schema name using `\dn` and set the `search_path` to use this _quoted_ schema name and the `public` schema: + +``` +set search_path to "server_2021-07-07T20:25:04.779Z_T75V6Y",public; +``` + +* During startup we initially have no non-public schema in use. We first run the migrations to update all tables in the `public` schema, then we call `sqldb.setRandomSearchSchema()` to activate a random per-execution schema, and we run the sproc creation code to generate all the stored procedures in this schema. This means that every invocation of PrairieLearn will have its own locally-scoped copy of the stored procedures which are the correct versions for its code. This lets us upgrade PrairieLearn servers one at a time, while old servers are still running with their own copies of their sprocs. When PrairieLearn first starts up it has `search_path = public`, but later it will have `search_path = "server_2021-07-07T20:25:04.779Z_T75V6Y",public` so that it will first search the random schema and then fall back to `public`. The naming convention for the random schema uses the local instance name, the date, and a random string. Note that schema names need to be quoted using double-quotations in `psql` because they contain characters such as hyphens. + +* For more details see `sprocs/array_and_number.sql` and comments in `server.js` near the call to `sqldb.setRandomSearchSchema()`. + + ## DB schema (simplified overview) * The most important tables in the database are shown in the diagram below (also as a [PDF image](simplified-models.pdf)). diff --git a/prairielib/lib/sql-db.js b/prairielib/lib/sql-db.js index e49ac7e7f2f..343eeeb9a4d 100644 --- a/prairielib/lib/sql-db.js +++ b/prairielib/lib/sql-db.js @@ -7,6 +7,8 @@ const { promisify } = require('util'); const error = require('./error'); +let searchSchema = null; + /** * Formats a string for debugging. * @@ -165,7 +167,11 @@ module.exports.close = function(callback) { module.exports.closeAsync = promisify(module.exports.close); /** - * Gets a new client from the connection pool. + * Gets a new client from the connection pool. If `err` is not null + * then `client` and `done` are undefined. If `err` is null then + * `client` is valid and can be used. The caller MUST call + * `done(client)` to release the client, whether or not errors occured + * while using `client`. * * @param {(error: Error | null, client: import("pg").PoolClient, done: (release?: any) => void) => void} callback */ @@ -180,7 +186,18 @@ module.exports.getClient = function(callback) { } return ERR(err, callback); // unconditionally return } - callback(null, client, done); + if (searchSchema != null) { + const setSearchPathSql = `SET search_path TO ${client.escapeIdentifier(searchSchema)},public`; + module.exports.queryWithClient(client, setSearchPathSql, {}, (err) => { + if (err) { + done(client); + return ERR(err, callback); // unconditionally return + } + callback(null, client, done); + }); + } else { + callback(null, client, done); + } }); }; @@ -403,31 +420,12 @@ module.exports.endTransactionAsync = promisify(module.exports.endTransaction); module.exports.query = function(sql, params, callback) { debug('query()', 'sql:', debugString(sql)); debug('query()', 'params:', debugParams(params)); - if (!pool) { - return callback(new Error('Connection pool is not open')); - } - pool.connect(function(err, client, done) { - const handleError = function(err) { - if (!err) return false; - if (client) { - done(client); - } - const sqlError = JSON.parse(JSON.stringify(err)); - sqlError.message = err.message; - err = error.addData(err, {sqlError: sqlError, sql: sql, sqlParams: params}); - ERR(err, callback); - return true; - }; - if (handleError(err)) return; - paramsToArray(sql, params, function(err, newSql, newParams) { - if (err) err = error.addData(err, {sql: sql, sqlParams: params}); + module.exports.getClient((err, client, done) => { + if (ERR(err, callback)) return; + module.exports.queryWithClient(client, sql, params, (err, result) => { + done(client); if (ERR(err, callback)) return; - client.query(newSql, newParams, function(err, result) { - if (handleError(err)) return; - done(); - debug('query() success', 'rowCount:', result.rowCount); - callback(null, result); - }); + callback(null, result); }); }); }; @@ -659,3 +657,61 @@ module.exports.callWithClientZeroOrOneRow = function(client, functionName, param * Errors if the function returns more than one row. */ module.exports.callWithClientZeroOrOneRowAsync = promisify(module.exports.callWithClientZeroOrOneRow); + +/** + * Set the schema to use for the search path. + * + * @param {string} schema - The schema name to use (can be "null" to unset the search path) + * @param {(error: Error | null) => void} callback + */ +module.exports.setSearchSchema = function(schema, callback) { + if (schema == null) { + searchSchema = schema; + return; + } + /* Note that as of 2021-06-29 escapeIdentifier() is undocumented. See: + * https://github.com/brianc/node-postgres/pull/396 + * https://github.com/brianc/node-postgres/issues/1978 + * https://www.postgresql.org/docs/12/sql-syntax-lexical.html + */ + module.exports.query(`CREATE SCHEMA IF NOT EXISTS ${pg.Client.prototype.escapeIdentifier(schema)}`, [], (err) => { + if (ERR(err, callback)) return; + // we only set searchSchema after CREATE to avoid the above query() call using searchSchema + searchSchema = schema; + callback(null); + }); +}; + +/** + * Get the schema that is currently used for the search path. + * + * @return {string} schema in use (may be "null" to indicate no schema) + */ +module.exports.getSearchSchema = function() { + return searchSchema; +}; + +/** + * Generate, set, and return a random schema name. + * + * @param {string} prefix - The prefix of the new schema, only the first 28 characters will be used (after lowercasing). + * @param {(error: Error | null, schema: String) => void} callback + */ +module.exports.setRandomSearchSchema = function(prefix, callback) { + // truncated prefix (max 28 characters) + const truncPrefix = prefix.substring(0, 28); + // timestamp in format YYYY-MM-DDTHH:MM:SS.SSSZ (guaranteed to not exceed 27 characters in the spec) + const timestamp = (new Date()).toISOString(); + // random 6-character suffix to avoid clashes (approx 2 billion possible values) + const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); + const suffix = _.times(6, function() {return _.sample(chars);}).join(''); + + // Schema is guaranteed to have length at most 63 (= 28 + 1 + 27 + 1 + 6), + // which is the default PostgreSQL identifier limit. + // Note that this schema name will need quoting because of characters like ':', '-', etc + const schema = `${truncPrefix}_${timestamp}_${suffix}`; + module.exports.setSearchSchema(schema, (err) => { + if (ERR(err, callback)) return; + callback(null, schema); + }); +}; diff --git a/server.js b/server.js index a4100d55b74..ea0bff91a8d 100644 --- a/server.js +++ b/server.js @@ -1136,6 +1136,21 @@ if (config.startServer) { callback(null); }); }, + function(callback) { + // We create and activate a random DB schema name + // (https://www.postgresql.org/docs/12/ddl-schemas.html) + // after we have run the migrations but before we create + // the sprocs. This means all tables (from migrations) are + // in the public schema, but all sprocs are in the random + // schema. Every server invocation thus has its own copy + // of its sprocs, allowing us to update servers while old + // servers are still running. See docs/dev-guide.md for + // more info. + sqldb.setRandomSearchSchema(config.instanceId, (err) => { + if (ERR(err, callback)) return; + callback(null); + }); + }, function(callback) { sprocs.init(function(err) { if (ERR(err, callback)) return; diff --git a/sprocs/access_tokens_delete.sql b/sprocs/access_tokens_delete.sql index b0357dd5cf1..7f7c1809c86 100644 --- a/sprocs/access_tokens_delete.sql +++ b/sprocs/access_tokens_delete.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION access_tokens_delete( id bigint, user_id bigint diff --git a/sprocs/access_tokens_insert.sql b/sprocs/access_tokens_insert.sql index 5b25d78b4fe..5d67adfd541 100644 --- a/sprocs/access_tokens_insert.sql +++ b/sprocs/access_tokens_insert.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION access_tokens_insert( user_id bigint, name text, diff --git a/sprocs/admin_assessment_question_number.sql b/sprocs/admin_assessment_question_number.sql index 68b00d8553a..88f2cd4bd2b 100644 --- a/sprocs/admin_assessment_question_number.sql +++ b/sprocs/admin_assessment_question_number.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION admin_assessment_question_number ( assessment_question_id bigint ) RETURNS text diff --git a/sprocs/administrators_delete_by_user_id.sql b/sprocs/administrators_delete_by_user_id.sql index 00d448d3fd3..c92cbe2f5ef 100644 --- a/sprocs/administrators_delete_by_user_id.sql +++ b/sprocs/administrators_delete_by_user_id.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION administrators_delete_by_user_id( user_id bigint, authn_user_id bigint diff --git a/sprocs/administrators_insert_by_user_uid.sql b/sprocs/administrators_insert_by_user_uid.sql index 0c9f870dccf..d1bc0de8459 100644 --- a/sprocs/administrators_insert_by_user_uid.sql +++ b/sprocs/administrators_insert_by_user_uid.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION administrators_insert_by_user_uid( uid text, authn_user_id bigint diff --git a/sprocs/array_and_number.sql b/sprocs/array_and_number.sql index fb209ff192f..828396de214 100644 --- a/sprocs/array_and_number.sql +++ b/sprocs/array_and_number.sql @@ -1,7 +1,10 @@ ---create types -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'array_and_number') THEN - CREATE TYPE array_and_number AS (arr DOUBLE PRECISION[], number INTEGER); - END IF; -END$$; +-- Ideally, we'd use something like `CREATE TYPE IF NOT EXISTS` here, but Postgres doesn't offer that. +-- We used to approximate this by checking `IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = ...)`. +-- However, now that we're creating sprocs and types in a local per-process schema, this would no longer work, +-- as the type would exist in `pg_type` but not necessarily in the schemas on the search path. +-- So, instead, we blindly create the type without checking if it first exists, as it should never exist since we're +-- creating it in a fresh, empty schema. If we needed to check, a good query is: +-- DO $$ BEGIN CREATE TYPE my_type AS (...); EXCEPTION WHEN duplicate_object THEN null; END $$; +-- See https://stackoverflow.com/questions/7624919/check-if-a-user-defined-type-already-exists-in-postgresql/48382296#48382296 + +CREATE TYPE array_and_number AS (arr DOUBLE PRECISION[], number INTEGER); diff --git a/sprocs/array_avg.sql b/sprocs/array_avg.sql index 488a575f3c9..cae14c75aeb 100644 --- a/sprocs/array_avg.sql +++ b/sprocs/array_avg.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION array_avg_sfunc ( state array_and_number, input DOUBLE PRECISION[] @@ -16,7 +16,7 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -CREATE OR REPLACE FUNCTION +CREATE FUNCTION array_avg_ffunc ( state array_and_number ) RETURNS DOUBLE PRECISION[] AS $$ @@ -29,7 +29,6 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -DROP AGGREGATE IF EXISTS array_avg (DOUBLE PRECISION[]) CASCADE; CREATE AGGREGATE array_avg (DOUBLE PRECISION[]) ( SFUNC = array_avg_sfunc, STYPE = array_and_number, diff --git a/sprocs/array_dot.sql b/sprocs/array_dot.sql index 8ee140c3f6f..a8dd914f6c1 100644 --- a/sprocs/array_dot.sql +++ b/sprocs/array_dot.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION array_dot( IN x DOUBLE PRECISION[], IN y DOUBLE PRECISION[], diff --git a/sprocs/array_histogram.sql b/sprocs/array_histogram.sql index d3eca284945..3f635023028 100644 --- a/sprocs/array_histogram.sql +++ b/sprocs/array_histogram.sql @@ -1,7 +1,7 @@ -- Based on: https://wiki.postgresql.org/wiki/Aggregate_Histogram -CREATE OR REPLACE FUNCTION +CREATE FUNCTION array_histogram_sfunc (state INTEGER[], val anyelement, thresholds anyarray) RETURNS INTEGER[] AS $$ DECLARE nbuckets INTEGER; @@ -28,7 +28,6 @@ END; $$ LANGUAGE plpgsql IMMUTABLE; -- Tell Postgres how to use the new function -DROP AGGREGATE IF EXISTS array_histogram (anyelement, anyarray) CASCADE; CREATE AGGREGATE array_histogram (anyelement, anyarray) ( SFUNC = array_histogram_sfunc, STYPE = INTEGER[] diff --git a/sprocs/array_increments_above_max.sql b/sprocs/array_increments_above_max.sql index 129387f2cb1..eb90143a9c8 100644 --- a/sprocs/array_increments_above_max.sql +++ b/sprocs/array_increments_above_max.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION array_increments_above_max( IN data double precision[], OUT increments double precision[] diff --git a/sprocs/array_product.sql b/sprocs/array_product.sql index 3a000e3e323..d262ca251ad 100644 --- a/sprocs/array_product.sql +++ b/sprocs/array_product.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION array_product( IN x DOUBLE PRECISION[], IN y DOUBLE PRECISION[], diff --git a/sprocs/array_var.sql b/sprocs/array_var.sql index 6f8744b0271..607ce969caf 100644 --- a/sprocs/array_var.sql +++ b/sprocs/array_var.sql @@ -1,10 +1,9 @@ ----------------------------------- ONLINE MEAN ----------------------------------- -- https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm -DROP TYPE IF EXISTS mean_and_index CASCADE; CREATE TYPE mean_and_index AS (mean DOUBLE PRECISION, index DOUBLE PRECISION); -CREATE OR REPLACE FUNCTION online_mean_sfunc ( +CREATE FUNCTION online_mean_sfunc ( prev_mean_and_index mean_and_index, input DOUBLE PRECISION ) RETURNS mean_and_index AS $$ @@ -27,7 +26,7 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -CREATE OR REPLACE FUNCTION online_mean_ffunc( +CREATE FUNCTION online_mean_ffunc( mean_and_index mean_and_index ) RETURNS DOUBLE PRECISION AS $$ BEGIN @@ -35,7 +34,6 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -DROP AGGREGATE IF EXISTS online_mean (DOUBLE PRECISION) CASCADE; CREATE AGGREGATE online_mean (DOUBLE PRECISION) ( STYPE = mean_and_index, SFUNC = online_mean_sfunc, @@ -45,10 +43,9 @@ CREATE AGGREGATE online_mean (DOUBLE PRECISION) ( -------------------------------- ONLINE VARIANCE -------------------------------- -- https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm -DROP TYPE IF EXISTS mean_and_var_and_index CASCADE; CREATE TYPE mean_and_var_and_index AS (mean DOUBLE PRECISION, variance DOUBLE PRECISION, index DOUBLE PRECISION); -CREATE OR REPLACE FUNCTION online_var_sfunc ( +CREATE FUNCTION online_var_sfunc ( prev_state mean_and_var_and_index, input DOUBLE PRECISION ) RETURNS mean_and_var_and_index AS $$ @@ -75,7 +72,7 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -CREATE OR REPLACE FUNCTION online_var_ffunc( +CREATE FUNCTION online_var_ffunc( state mean_and_var_and_index ) RETURNS DOUBLE PRECISION AS $$ BEGIN @@ -83,7 +80,6 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -DROP AGGREGATE IF EXISTS online_var (DOUBLE PRECISION) CASCADE; CREATE AGGREGATE online_var (DOUBLE PRECISION) ( STYPE = mean_and_var_and_index, SFUNC = online_var_sfunc, @@ -93,7 +89,7 @@ CREATE AGGREGATE online_var (DOUBLE PRECISION) ( ------------------------------ ONLINE ARRAY VARIANCE ------------------------------ -- https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm -CREATE OR REPLACE FUNCTION array_var_sfunc ( +CREATE FUNCTION array_var_sfunc ( prev_state mean_and_var_and_index[], input DOUBLE PRECISION[] ) RETURNS mean_and_var_and_index[] AS $$ @@ -118,7 +114,7 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -CREATE OR REPLACE FUNCTION array_var_ffunc( +CREATE FUNCTION array_var_ffunc( state mean_and_var_and_index[] ) RETURNS DOUBLE PRECISION[] AS $$ DECLARE @@ -136,7 +132,6 @@ BEGIN END; $$ LANGUAGE plpgsql IMMUTABLE; -DROP AGGREGATE IF EXISTS array_var (DOUBLE PRECISION[]) CASCADE; CREATE AGGREGATE array_var (DOUBLE PRECISION[]) ( STYPE = mean_and_var_and_index[], SFUNC = array_var_sfunc, diff --git a/sprocs/assessment_groups_add_member.sql b/sprocs/assessment_groups_add_member.sql index 24a8788f729..2a6cd9d94d3 100644 --- a/sprocs/assessment_groups_add_member.sql +++ b/sprocs/assessment_groups_add_member.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_groups_add_member(bigint,bigint,text,bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_groups_add_member( assessment_id bigint, arg_group_id bigint, diff --git a/sprocs/assessment_groups_copy.sql b/sprocs/assessment_groups_copy.sql index a58126ac21b..c6e8ebb2711 100644 --- a/sprocs/assessment_groups_copy.sql +++ b/sprocs/assessment_groups_copy.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_groups_copy( assessment_id bigint, copying_assessment_id bigint, diff --git a/sprocs/assessment_groups_delete_all.sql b/sprocs/assessment_groups_delete_all.sql index a12d840760a..991920cb5fe 100644 --- a/sprocs/assessment_groups_delete_all.sql +++ b/sprocs/assessment_groups_delete_all.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_groups_delete_all( assessment_id bigint, authn_user_id bigint diff --git a/sprocs/assessment_groups_delete_group.sql b/sprocs/assessment_groups_delete_group.sql index 60cfc0a2e84..8176ffb3b26 100644 --- a/sprocs/assessment_groups_delete_group.sql +++ b/sprocs/assessment_groups_delete_group.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_groups_delete_group(bigint,bigint,bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_groups_delete_group( assessment_id bigint, arg_group_id bigint, diff --git a/sprocs/assessment_groups_delete_member.sql b/sprocs/assessment_groups_delete_member.sql index 4f24eb5655a..a190a01d925 100644 --- a/sprocs/assessment_groups_delete_member.sql +++ b/sprocs/assessment_groups_delete_member.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_groups_delete_member(bigint,bigint,text,bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_groups_delete_member( assessment_id bigint, arg_group_id bigint, diff --git a/sprocs/assessment_groups_update.sql b/sprocs/assessment_groups_update.sql index cd8be4b5763..a0d131c4368 100644 --- a/sprocs/assessment_groups_update.sql +++ b/sprocs/assessment_groups_update.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_groups_update( IN arg_assessment_id bigint, IN update_list text[][], -- [[groupName1, uid1], [groupName2, uid2], ...] diff --git a/sprocs/assessment_instance_label.sql b/sprocs/assessment_instance_label.sql index 003a366f903..f1999be3b6e 100644 --- a/sprocs/assessment_instance_label.sql +++ b/sprocs/assessment_instance_label.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instance_label( ai assessment_instances, a assessments, diff --git a/sprocs/assessment_instances_close.sql b/sprocs/assessment_instances_close.sql index 5b471956cb5..f22b134372f 100644 --- a/sprocs/assessment_instances_close.sql +++ b/sprocs/assessment_instances_close.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_close ( assessment_instance_id bigint, authn_user_id bigint diff --git a/sprocs/assessment_instances_delete.sql b/sprocs/assessment_instances_delete.sql index ba2438fc9f5..7d5a5891385 100644 --- a/sprocs/assessment_instances_delete.sql +++ b/sprocs/assessment_instances_delete.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_delete( assessment_instance_id bigint, authn_user_id bigint diff --git a/sprocs/assessment_instances_delete_all.sql b/sprocs/assessment_instances_delete_all.sql index 87ce2bb1bc5..89a49a1dd59 100644 --- a/sprocs/assessment_instances_delete_all.sql +++ b/sprocs/assessment_instances_delete_all.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_delete_all( assessment_id bigint, authn_user_id bigint diff --git a/sprocs/assessment_instances_duration.sql b/sprocs/assessment_instances_duration.sql index 9d5f6508c86..5ee6d8176e4 100644 --- a/sprocs/assessment_instances_duration.sql +++ b/sprocs/assessment_instances_duration.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_duration( IN assessment_instance_id bigint, OUT duration interval diff --git a/sprocs/assessment_instances_ensure_open.sql b/sprocs/assessment_instances_ensure_open.sql index 9242314279e..cd49d0ab7b9 100644 --- a/sprocs/assessment_instances_ensure_open.sql +++ b/sprocs/assessment_instances_ensure_open.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_ensure_open ( assessment_instance_id bigint ) RETURNS void diff --git a/sprocs/assessment_instances_grade.sql b/sprocs/assessment_instances_grade.sql index 766aa63338f..5e2089cec2e 100644 --- a/sprocs/assessment_instances_grade.sql +++ b/sprocs/assessment_instances_grade.sql @@ -1,9 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_grade(bigint,bigint,integer,boolean); -DROP FUNCTION IF EXISTS assessment_instances_grade(bigint,bigint,integer,boolean,boolean); -DROP FUNCTION IF EXISTS assessment_points(bigint,integer); -DROP FUNCTION IF EXISTS assessment_points(bigint,integer,boolean); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_grade( IN assessment_instance_id bigint, IN authn_user_id bigint, diff --git a/sprocs/assessment_instances_insert.sql b/sprocs/assessment_instances_insert.sql index 4a7b65b4b4f..9f635bf778e 100644 --- a/sprocs/assessment_instances_insert.sql +++ b/sprocs/assessment_instances_insert.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_insert(bigint,bigint,bigint,enum_mode,integer,timestamp with time zone); -DROP FUNCTION IF EXISTS assessment_instances_insert(bigint,bigint,boolean,bigint,enum_mode,integer,timestamp with time zone); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_insert( IN assessment_id bigint, IN user_id bigint, diff --git a/sprocs/assessment_instances_lock.sql b/sprocs/assessment_instances_lock.sql index 404476973d8..6c77186e7ed 100644 --- a/sprocs/assessment_instances_lock.sql +++ b/sprocs/assessment_instances_lock.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_lock ( assessment_instance_id bigint ) RETURNS void diff --git a/sprocs/assessment_instances_points.sql b/sprocs/assessment_instances_points.sql index 647b3b1545d..573126c4891 100644 --- a/sprocs/assessment_instances_points.sql +++ b/sprocs/assessment_instances_points.sql @@ -1,9 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_points(bigint,integer,boolean); -DROP FUNCTION IF EXISTS assessment_instances_points(bigint); -DROP FUNCTION IF EXISTS zones_points(BIGINT); -DROP FUNCTION IF EXISTS zones_max_points(BIGINT); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_points( assessment_instance_id BIGINT ) RETURNS TABLE ( diff --git a/sprocs/assessment_instances_regrade.sql b/sprocs/assessment_instances_regrade.sql index 1fb7c6edc44..916f3789754 100644 --- a/sprocs/assessment_instances_regrade.sql +++ b/sprocs/assessment_instances_regrade.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_regrade( IN assessment_instance_id bigint, IN authn_user_id bigint, diff --git a/sprocs/assessment_instances_select_for_auto_close.sql b/sprocs/assessment_instances_select_for_auto_close.sql index 7d96ec0b86d..012cf85aa59 100644 --- a/sprocs/assessment_instances_select_for_auto_close.sql +++ b/sprocs/assessment_instances_select_for_auto_close.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_select_for_auto_close(integer); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_select_for_auto_close( age_mins integer -- time in minutes (after last activity) when we auto-close an exam ) RETURNS TABLE (assessment_instance_id bigint) diff --git a/sprocs/assessment_instances_select_log.sql b/sprocs/assessment_instances_select_log.sql index 0f5c80da39b..3e53d4a5fc7 100644 --- a/sprocs/assessment_instances_select_log.sql +++ b/sprocs/assessment_instances_select_log.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_select_log(bigint); -DROP FUNCTION IF EXISTS assessment_instances_select_log(bigint,boolean); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_select_log ( ai_id bigint, include_files boolean diff --git a/sprocs/assessment_instances_update.sql b/sprocs/assessment_instances_update.sql index ca49a86b6ab..7af451eed66 100644 --- a/sprocs/assessment_instances_update.sql +++ b/sprocs/assessment_instances_update.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_update(bigint,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_update ( IN assessment_instance_id bigint, IN authn_user_id bigint, diff --git a/sprocs/assessment_instances_update_points.sql b/sprocs/assessment_instances_update_points.sql index 348e0fd0464..c3f5c400964 100644 --- a/sprocs/assessment_instances_update_points.sql +++ b/sprocs/assessment_instances_update_points.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_update_points(bigint,double precision,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_update_points( IN assessment_instance_id bigint, IN new_points double precision, diff --git a/sprocs/assessment_instances_update_score_perc.sql b/sprocs/assessment_instances_update_score_perc.sql index 40811ccb874..d7a4c94c70a 100644 --- a/sprocs/assessment_instances_update_score_perc.sql +++ b/sprocs/assessment_instances_update_score_perc.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS assessment_instances_update_score_perc(bigint,double precision,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_instances_update_score_perc( IN assessment_instance_id bigint, IN new_score_perc double precision, diff --git a/sprocs/assessment_label.sql b/sprocs/assessment_label.sql index 945abc8fce0..be2de3d6527 100644 --- a/sprocs/assessment_label.sql +++ b/sprocs/assessment_label.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_label( a assessments, aset assessment_sets diff --git a/sprocs/assessment_questions_calculate_stats.sql b/sprocs/assessment_questions_calculate_stats.sql index e16feef58b2..6293eed6d05 100644 --- a/sprocs/assessment_questions_calculate_stats.sql +++ b/sprocs/assessment_questions_calculate_stats.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_questions_calculate_stats ( assessment_question_id_param bigint ) RETURNS VOID diff --git a/sprocs/assessment_questions_calculate_stats_for_assessment.sql b/sprocs/assessment_questions_calculate_stats_for_assessment.sql index 4e328105e91..b6ffe96c5b5 100644 --- a/sprocs/assessment_questions_calculate_stats_for_assessment.sql +++ b/sprocs/assessment_questions_calculate_stats_for_assessment.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessment_questions_calculate_stats_for_assessment ( assessment_id_var bigint ) RETURNS VOID diff --git a/sprocs/assessments_duration_stats.sql b/sprocs/assessments_duration_stats.sql index a716cbd121f..4febb0d6914 100644 --- a/sprocs/assessments_duration_stats.sql +++ b/sprocs/assessments_duration_stats.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessments_duration_stats ( IN assessment_id bigint, OUT min interval, diff --git a/sprocs/assessments_format.sql b/sprocs/assessments_format.sql index 08f85fb71dc..db78fce89e1 100644 --- a/sprocs/assessments_format.sql +++ b/sprocs/assessments_format.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessments_format( assessment_id bigint ) RETURNS JSONB diff --git a/sprocs/assessments_format_for_question.sql b/sprocs/assessments_format_for_question.sql index dcf753eb18f..73e53689810 100644 --- a/sprocs/assessments_format_for_question.sql +++ b/sprocs/assessments_format_for_question.sql @@ -2,9 +2,7 @@ -- question_id for course instance course_instance_id. If skip_assessment_id -- is provided then that individual assessment is not included. -DROP FUNCTION IF EXISTS assessments_for_question(bigint,bigint,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessments_format_for_question( question_id bigint, course_instance_id bigint, diff --git a/sprocs/assessments_stats.sql b/sprocs/assessments_stats.sql index 785aa18b67a..9b99e744bc7 100644 --- a/sprocs/assessments_stats.sql +++ b/sprocs/assessments_stats.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION assessments_stats ( IN assessment_id bigint, OUT number integer, diff --git a/sprocs/authz_assessment.sql b/sprocs/authz_assessment.sql index 2eb62829ecc..3aca86ef1ab 100644 --- a/sprocs/authz_assessment.sql +++ b/sprocs/authz_assessment.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS authz_assessment(bigint,jsonb); -DROP FUNCTION IF EXISTS authz_assessment(bigint,jsonb,text); -DROP FUNCTION IF EXISTS authz_assessment(bigint,jsonb,timestamptz,text); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION authz_assessment ( IN assessment_id bigint, IN authz_data JSONB, diff --git a/sprocs/authz_assessment_instance.sql b/sprocs/authz_assessment_instance.sql index 57a0178d12c..4ba20b0ad4b 100644 --- a/sprocs/authz_assessment_instance.sql +++ b/sprocs/authz_assessment_instance.sql @@ -1,9 +1,4 @@ -DROP FUNCTION IF EXISTS authz_assessment_instance(bigint,jsonb); -DROP FUNCTION IF EXISTS authz_assessment_instance(bigint,jsonb,text); -DROP FUNCTION IF EXISTS authz_assessment_instance(bigint,jsonb,timestamp with time zone,text); -DROP FUNCTION IF EXISTS authz_assessment_instance(bigint,jsonb,timestamp with time zone,text, boolean); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION authz_assessment_instance ( IN assessment_instance_id bigint, IN authz_data JSONB, diff --git a/sprocs/authz_course.sql b/sprocs/authz_course.sql index ca06ae13bf9..b5cd5c46ad2 100644 --- a/sprocs/authz_course.sql +++ b/sprocs/authz_course.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION authz_course( user_id bigint, course_id bigint, diff --git a/sprocs/authz_course_instance.sql b/sprocs/authz_course_instance.sql index 73688f55956..0e527fe4f34 100644 --- a/sprocs/authz_course_instance.sql +++ b/sprocs/authz_course_instance.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS authz_course_instance(bigint,bigint,boolean); -DROP FUNCTION IF EXISTS authz_course_instance(bigint,bigint,boolean,timestamptz); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION authz_course_instance( user_id bigint, course_instance_id bigint, diff --git a/sprocs/base64_safe_decode.sql b/sprocs/base64_safe_decode.sql index 97c3782ae89..8213aa2f9b3 100644 --- a/sprocs/base64_safe_decode.sql +++ b/sprocs/base64_safe_decode.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS base64_safe_decode(text); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION base64_safe_decode( IN base64_text text ) RETURNS bytea diff --git a/sprocs/check_assessment_access.sql b/sprocs/check_assessment_access.sql index cf57889accb..183fa5d0c11 100644 --- a/sprocs/check_assessment_access.sql +++ b/sprocs/check_assessment_access.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS check_assessment_access(bigint,enum_mode,enum_role,text,timestamp with time zone); -DROP FUNCTION IF EXISTS check_assessment_access(bigint,enum_mode,enum_role,text,timestamp with time zone,text); -DROP FUNCTION IF EXISTS check_assessment_access(bigint,enum_mode,enum_role,bigint,text,timestamp with time zone,text); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION check_assessment_access ( IN assessment_id bigint, IN authz_mode enum_mode, diff --git a/sprocs/check_assessment_access_rule.sql b/sprocs/check_assessment_access_rule.sql index 2f0d50891d9..2563e176ddf 100644 --- a/sprocs/check_assessment_access_rule.sql +++ b/sprocs/check_assessment_access_rule.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS check_assessment_access_rule(assessment_access_rules,enum_mode,enum_role,text,timestamp with time zone,boolean); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION check_assessment_access_rule ( IN assessment_access_rule assessment_access_rules, IN mode enum_mode, diff --git a/sprocs/check_course_instance_access.sql b/sprocs/check_course_instance_access.sql index b888fa6c9c4..e16de08c6d5 100644 --- a/sprocs/check_course_instance_access.sql +++ b/sprocs/check_course_instance_access.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS check_course_instance_access(bigint, enum_role, text, timestamptz); -DROP FUNCTION IF EXISTS check_course_instance_access(bigint, enum_role, text, bigint, timestamptz); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION check_course_instance_access ( course_instance_id bigint, role enum_role, diff --git a/sprocs/check_course_instance_access_rule.sql b/sprocs/check_course_instance_access_rule.sql index b64e06e59d5..ed99749653c 100644 --- a/sprocs/check_course_instance_access_rule.sql +++ b/sprocs/check_course_instance_access_rule.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS check_course_instance_access_rule(course_instance_access_rules, enum_role, text, timestamptz); -DROP FUNCTION IF EXISTS check_course_instance_access_rule(course_instance_access_rules, enum_role, text, bigint, timestamptz); -DROP FUNCTION IF EXISTS check_course_instance_access_rule(course_instance_access_rules, enum_role, text, bigint, bigint, timestamptz); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION check_course_instance_access_rule ( course_instance_access_rule course_instance_access_rules, role enum_role, diff --git a/sprocs/chunks_insert.sql b/sprocs/chunks_insert.sql index d969a2c0136..388a224bfc8 100644 --- a/sprocs/chunks_insert.sql +++ b/sprocs/chunks_insert.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION chunks_insert( IN in_course_id bigint, IN generated_chunks json[] diff --git a/sprocs/config_select.sql b/sprocs/config_select.sql index f2a4bb3c8fc..5698eb4b872 100644 --- a/sprocs/config_select.sql +++ b/sprocs/config_select.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION config_select( IN key text, OUT value text diff --git a/sprocs/course_instances_instructor_can_view.sql b/sprocs/course_instances_instructor_can_view.sql index d7070808b70..28b3cff7003 100644 --- a/sprocs/course_instances_instructor_can_view.sql +++ b/sprocs/course_instances_instructor_can_view.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION course_instances_instructor_can_view ( IN user_id bigint, IN is_administrator boolean, diff --git a/sprocs/course_permissions_delete.sql b/sprocs/course_permissions_delete.sql index 94ef5462a5f..f30d115aba8 100644 --- a/sprocs/course_permissions_delete.sql +++ b/sprocs/course_permissions_delete.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION course_permissions_delete( course_id bigint, user_id bigint, diff --git a/sprocs/course_permissions_insert_by_user_uid.sql b/sprocs/course_permissions_insert_by_user_uid.sql index cc7785bfd6f..b90af69c955 100644 --- a/sprocs/course_permissions_insert_by_user_uid.sql +++ b/sprocs/course_permissions_insert_by_user_uid.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION course_permissions_insert_by_user_uid( course_id bigint, uid text, diff --git a/sprocs/course_permissions_update_role.sql b/sprocs/course_permissions_update_role.sql index 54dfc13f8a8..2e20073aebe 100644 --- a/sprocs/course_permissions_update_role.sql +++ b/sprocs/course_permissions_update_role.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION course_permissions_update_role( course_id bigint, user_id bigint, diff --git a/sprocs/course_requests_insert.sql b/sprocs/course_requests_insert.sql index 54f600e9b9a..13922b82513 100644 --- a/sprocs/course_requests_insert.sql +++ b/sprocs/course_requests_insert.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION course_requests_insert( IN user_id bigint, IN short_name text, diff --git a/sprocs/courses_delete.sql b/sprocs/courses_delete.sql index cf0e36fcb5b..5210b5f7e00 100644 --- a/sprocs/courses_delete.sql +++ b/sprocs/courses_delete.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION courses_delete( course_id bigint, authn_user_id bigint diff --git a/sprocs/courses_insert.sql b/sprocs/courses_insert.sql index 4074d3f47f8..281f6e82a42 100644 --- a/sprocs/courses_insert.sql +++ b/sprocs/courses_insert.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS courses_insert(text,text,text,text,bigint); -DROP FUNCTION IF EXISTS courses_insert(text,text,text,text,text,bigint); -DROP FUNCTION IF EXISTS courses_insert(bigint,text,text,text,text,text,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION courses_insert( IN institution_id bigint, IN short_name text, diff --git a/sprocs/courses_update_column.sql b/sprocs/courses_update_column.sql index 9cb48a8d4e0..acfab2d5dc9 100644 --- a/sprocs/courses_update_column.sql +++ b/sprocs/courses_update_column.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION courses_update_column( course_id bigint, column_name text, diff --git a/sprocs/courses_user_can_edit.sql b/sprocs/courses_user_can_edit.sql index fec9790e7d8..9948fc282e7 100644 --- a/sprocs/courses_user_can_edit.sql +++ b/sprocs/courses_user_can_edit.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION courses_user_can_edit ( IN user_id bigint, IN is_administrator boolean, diff --git a/sprocs/courses_user_can_view.sql b/sprocs/courses_user_can_view.sql index c9c93d1d74b..d11c0691ab3 100644 --- a/sprocs/courses_user_can_view.sql +++ b/sprocs/courses_user_can_view.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION courses_user_can_view ( IN user_id bigint, IN is_administrator boolean, diff --git a/sprocs/dump_to_csv.sql b/sprocs/dump_to_csv.sql index 3c958c1ec17..5f79c8ac4ee 100644 --- a/sprocs/dump_to_csv.sql +++ b/sprocs/dump_to_csv.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION dump_to_csv( prefix text, anon boolean DEFAULT false diff --git a/sprocs/files_delete.sql b/sprocs/files_delete.sql index eb9b5d84f72..f6bdf8cd3d0 100644 --- a/sprocs/files_delete.sql +++ b/sprocs/files_delete.sql @@ -1,5 +1,4 @@ - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION files_delete( IN file_id bigint, IN authn_user_id bigint diff --git a/sprocs/files_insert.sql b/sprocs/files_insert.sql index 5498bcb3d52..a7a1777665b 100644 --- a/sprocs/files_insert.sql +++ b/sprocs/files_insert.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS files_insert(text,text,text,bigint,bigint,bigint,bigint); -DROP FUNCTION IF EXISTS files_insert(text,text,text,bigint,bigint,bigint,bigint,enum_file_storage_type); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION files_insert( IN display_filename text, IN storage_filename text, diff --git a/sprocs/first.sql b/sprocs/first.sql index a8bcc5d6219..f863689b805 100644 --- a/sprocs/first.sql +++ b/sprocs/first.sql @@ -1,12 +1,12 @@ -- Create a function that always returns the first non-NULL item -CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement ) +CREATE FUNCTION first_agg ( anyelement, anyelement ) RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$ SELECT $1; $$; -- And then wrap an aggregate around it -CREATE AGGREGATE public.FIRST ( - sfunc = public.first_agg, +CREATE AGGREGATE FIRST ( + sfunc = first_agg, basetype = anyelement, stype = anyelement -); \ No newline at end of file +); diff --git a/sprocs/format_date_full.sql b/sprocs/format_date_full.sql index 82729700e49..0bb767b8a61 100644 --- a/sprocs/format_date_full.sql +++ b/sprocs/format_date_full.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS format_date_full(timestamp with time zone, text); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION format_date_full ( d timestamp with time zone, display_timezone text diff --git a/sprocs/format_date_full_compact.sql b/sprocs/format_date_full_compact.sql index 1746b6fa8f3..86bef82b7a9 100644 --- a/sprocs/format_date_full_compact.sql +++ b/sprocs/format_date_full_compact.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS format_date_full_compact(timestamp with time zone); -DROP FUNCTION IF EXISTS format_date_full_compact(timestamp with time zone,text); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION format_date_full_compact ( d timestamp with time zone, display_timezone text diff --git a/sprocs/format_date_full_compact_ms.sql b/sprocs/format_date_full_compact_ms.sql index a5f6bc34486..330f7dacc41 100644 --- a/sprocs/format_date_full_compact_ms.sql +++ b/sprocs/format_date_full_compact_ms.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS format_date_full_compact_ms(timestamp with time zone,text); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION format_date_full_compact_ms ( d timestamp with time zone, display_timezone text diff --git a/sprocs/format_date_iso8601.sql b/sprocs/format_date_iso8601.sql index e73ad432f21..247610dfb2e 100644 --- a/sprocs/format_date_iso8601.sql +++ b/sprocs/format_date_iso8601.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS format_date_iso8601(timestamptz,text); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION format_date_iso8601 ( d timestamp with time zone, display_timezone text diff --git a/sprocs/format_date_only_no_tz.sql b/sprocs/format_date_only_no_tz.sql index 47b6fe95f65..0b95f064c41 100644 --- a/sprocs/format_date_only_no_tz.sql +++ b/sprocs/format_date_only_no_tz.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS format_date_only_no_tz(timestamp with time zone,text); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION format_date_only_no_tz ( d timestamp with time zone, display_timezone text diff --git a/sprocs/format_date_short.sql b/sprocs/format_date_short.sql index 4a119aab413..ce094f491c2 100644 --- a/sprocs/format_date_short.sql +++ b/sprocs/format_date_short.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS format_date_short(timestamp with time zone,text); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION format_date_short ( d timestamp with time zone, display_timezone text diff --git a/sprocs/format_interval.sql b/sprocs/format_interval.sql index a2157a94608..ea596feb8c2 100644 --- a/sprocs/format_interval.sql +++ b/sprocs/format_interval.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION format_interval(d interval) RETURNS text AS $$ +CREATE FUNCTION format_interval(d interval) RETURNS text AS $$ WITH parts AS ( SELECT div(CAST(floor(EXTRACT(EPOCH FROM d)) AS integer), 60 * 60 * 24) AS days, diff --git a/sprocs/format_interval_short.sql b/sprocs/format_interval_short.sql index 0bdc049038f..2c35c679bce 100644 --- a/sprocs/format_interval_short.sql +++ b/sprocs/format_interval_short.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION format_interval_short(d interval) RETURNS text AS $$ +CREATE FUNCTION format_interval_short(d interval) RETURNS text AS $$ DECLARE days integer; hours integer; diff --git a/sprocs/grader_loads_current.sql b/sprocs/grader_loads_current.sql index 1ce4381207c..3c756b7ba6d 100644 --- a/sprocs/grader_loads_current.sql +++ b/sprocs/grader_loads_current.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS grader_loads_current(text,interval); -DROP FUNCTION IF EXISTS grader_loads_current(text,interval,interval,double precision, double precision); -DROP FUNCTION IF EXISTS grader_loads_current(text,interval,interval,double precision, double precision, double precision); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grader_loads_current( IN queue_name text, IN grader_load_interval interval, -- how far back to look to estimate current load diff --git a/sprocs/grading_job_status.sql b/sprocs/grading_job_status.sql index d7b258fe915..35480567097 100644 --- a/sprocs/grading_job_status.sql +++ b/sprocs/grading_job_status.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grading_job_status( grading_job_id bigint ) RETURNS TEXT AS $$ diff --git a/sprocs/grading_jobs_insert.sql b/sprocs/grading_jobs_insert.sql index aac051b9ef9..10c8c981382 100644 --- a/sprocs/grading_jobs_insert.sql +++ b/sprocs/grading_jobs_insert.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS grading_jobs_insert(bigint,bigint,boolean,jsonb,jsonb,double precision,jsonb,jsonb,jsonb,jsonb); - -DROP FUNCTION IF EXISTS grading_jobs_insert(bigint,bigint,boolean,boolean,jsonb,jsonb,double precision,jsonb,jsonb,jsonb,jsonb); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grading_jobs_insert ( IN submission_id bigint, IN authn_user_id bigint, diff --git a/sprocs/grading_jobs_insert_external_manual.sql b/sprocs/grading_jobs_insert_external_manual.sql index 44981991a5a..236f457c86e 100644 --- a/sprocs/grading_jobs_insert_external_manual.sql +++ b/sprocs/grading_jobs_insert_external_manual.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grading_jobs_insert_external_manual ( IN submission_id bigint, IN authn_user_id bigint, diff --git a/sprocs/grading_jobs_insert_internal.sql b/sprocs/grading_jobs_insert_internal.sql index 465fb10e40f..c5134b3e820 100644 --- a/sprocs/grading_jobs_insert_internal.sql +++ b/sprocs/grading_jobs_insert_internal.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS grading_jobs_insert_internal(bigint,bigint,boolean,boolean,jsonb,jsonb,double precision,jsonb,jsonb,jsonb,jsonb); - -DROP FUNCTION IF EXISTS grading_jobs_insert_internal(bigint,bigint,boolean,jsonb,jsonb,double precision,jsonb,jsonb,jsonb,jsonb); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grading_jobs_insert_internal ( IN submission_id bigint, IN authn_user_id bigint, diff --git a/sprocs/grading_jobs_lock.sql b/sprocs/grading_jobs_lock.sql index e02e05f1106..067f8f25619 100644 --- a/sprocs/grading_jobs_lock.sql +++ b/sprocs/grading_jobs_lock.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grading_jobs_lock ( grading_job_id bigint ) RETURNS void diff --git a/sprocs/grading_jobs_process_external.sql b/sprocs/grading_jobs_process_external.sql index 799bea80765..90793a32987 100644 --- a/sprocs/grading_jobs_process_external.sql +++ b/sprocs/grading_jobs_process_external.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grading_jobs_process_external( grading_job_id bigint, score double precision, diff --git a/sprocs/grading_jobs_stats_day.sql b/sprocs/grading_jobs_stats_day.sql index 2e3a4f2fbc6..b74e8e0d701 100644 --- a/sprocs/grading_jobs_stats_day.sql +++ b/sprocs/grading_jobs_stats_day.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS grading_jobs_stats_day(); -DROP FUNCTION IF EXISTS grading_jobs_stats_day(bigint,double precision,double precision,double precision,double precision,double precision); -DROP FUNCTION IF EXISTS grading_jobs_stats_day(bigint,double precision,double precision,double precision,double precision,double precision,double precision,double precision,double precision,double precision,double precision); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION grading_jobs_stats_day( OUT count bigint, OUT delta_total double precision, diff --git a/sprocs/group_info.sql b/sprocs/group_info.sql index ec053221210..f63d08b2e61 100644 --- a/sprocs/group_info.sql +++ b/sprocs/group_info.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS group_info(bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION group_info ( IN assessment_id bigint ) RETURNS TABLE ( diff --git a/sprocs/group_users_insert.sql b/sprocs/group_users_insert.sql index 3aa6c4ff0a7..5159a3001ae 100644 --- a/sprocs/group_users_insert.sql +++ b/sprocs/group_users_insert.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS group_users_insert(bigint,bigint,bigint,text,text); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION group_users_insert ( arg_assessment_id bigint, arg_user_id bigint, diff --git a/sprocs/groups_uid_list.sql b/sprocs/groups_uid_list.sql index c9a7abb221b..156bfe6f1a0 100644 --- a/sprocs/groups_uid_list.sql +++ b/sprocs/groups_uid_list.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS groups_uid_list(bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION groups_uid_list ( IN group_id bigint, OUT uid_list text[] diff --git a/sprocs/histogram.sql b/sprocs/histogram.sql index 4da8b382ff1..cfeab3cbab7 100644 --- a/sprocs/histogram.sql +++ b/sprocs/histogram.sql @@ -1,10 +1,7 @@ -- Based on: https://wiki.postgresql.org/wiki/Aggregate_Histogram -DROP FUNCTION IF EXISTS histogram_sfunc(INTEGER[], REAL, REAL, REAL, INTEGER) CASCADE; -DROP FUNCTION IF EXISTS histogram_sfunc(INTEGER[], DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION, INTEGER) CASCADE; - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION histogram_sfunc ( state INTEGER[], val DOUBLE PRECISION, @@ -35,9 +32,6 @@ END; $$ LANGUAGE plpgsql IMMUTABLE; -- Tell Postgres how to use the new function -DROP AGGREGATE IF EXISTS histogram (INTEGER, REAL, REAL, INTEGER) CASCADE; -DROP AGGREGATE IF EXISTS histogram (REAL, REAL, REAL, INTEGER) CASCADE; -DROP AGGREGATE IF EXISTS histogram (DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION, INTEGER) CASCADE; CREATE AGGREGATE histogram (DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION, INTEGER) ( SFUNC = histogram_sfunc, STYPE = INTEGER[] diff --git a/sprocs/index.js b/sprocs/index.js index f699116fb10..04161683a87 100644 --- a/sprocs/index.js +++ b/sprocs/index.js @@ -65,7 +65,6 @@ module.exports = { 'assessments_format_for_question.sql', 'tags_for_question.sql', 'random_unique.sql', - 'random_string.sql', 'question_order.sql', 'authz_assessment.sql', 'authz_assessment_instance.sql', diff --git a/sprocs/input_date.sql b/sprocs/input_date.sql index 0e3091be464..1b6fc6b0d56 100644 --- a/sprocs/input_date.sql +++ b/sprocs/input_date.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION input_date ( date_string text, -- can be either '2016-07-24T16:52:48' or '2016-07-24 16:52:48' display_timezone text diff --git a/sprocs/instance_question_select_manual_grading_objects.sql b/sprocs/instance_question_select_manual_grading_objects.sql index 1196553e924..a5703f1da6a 100644 --- a/sprocs/instance_question_select_manual_grading_objects.sql +++ b/sprocs/instance_question_select_manual_grading_objects.sql @@ -1,9 +1,6 @@ --- BLOCK instance_question_select_last_variant_with_submission -DROP FUNCTION IF EXISTS instance_question_select_manual_grading_objects(bigint); - -- Retrieves the last variant for an instance question and last submission for the variant. -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_question_select_manual_grading_objects( IN iq_id bigint, OUT question jsonb, diff --git a/sprocs/instance_questions_calculate_stats.sql b/sprocs/instance_questions_calculate_stats.sql index 486ea892b32..9ab9e6609c1 100644 --- a/sprocs/instance_questions_calculate_stats.sql +++ b/sprocs/instance_questions_calculate_stats.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_calculate_stats( instance_question_id_param bigint ) RETURNS VOID diff --git a/sprocs/instance_questions_ensure_open.sql b/sprocs/instance_questions_ensure_open.sql index ff662b509bb..86378148dbe 100644 --- a/sprocs/instance_questions_ensure_open.sql +++ b/sprocs/instance_questions_ensure_open.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_ensure_open ( instance_question_id bigint ) RETURNS void diff --git a/sprocs/instance_questions_grade.sql b/sprocs/instance_questions_grade.sql index 8055a884825..dac1369a097 100644 --- a/sprocs/instance_questions_grade.sql +++ b/sprocs/instance_questions_grade.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_grade(bigint,boolean,bigint); -DROP FUNCTION IF EXISTS instance_questions_grade(bigint,double precision,bigint); -DROP FUNCTION IF EXISTS instance_questions_grade(bigint,double precision,bigint,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_grade( instance_question_id bigint, submission_score DOUBLE PRECISION, diff --git a/sprocs/instance_questions_lock.sql b/sprocs/instance_questions_lock.sql index d5d8201f4a6..b553322fdb6 100644 --- a/sprocs/instance_questions_lock.sql +++ b/sprocs/instance_questions_lock.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_lock ( instance_question_id bigint ) RETURNS void diff --git a/sprocs/instance_questions_next_allowed_grade.sql b/sprocs/instance_questions_next_allowed_grade.sql index 3e185748f27..5363331b1b0 100644 --- a/sprocs/instance_questions_next_allowed_grade.sql +++ b/sprocs/instance_questions_next_allowed_grade.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_next_allowed_grade(bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_next_allowed_grade ( IN instance_question_id BIGINT, OUT allow_grade_date TIMESTAMPTZ, diff --git a/sprocs/instance_questions_points.sql b/sprocs/instance_questions_points.sql index 425fd50270f..e9f1e64955d 100644 --- a/sprocs/instance_questions_points.sql +++ b/sprocs/instance_questions_points.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_points(bigint,boolean); -DROP FUNCTION IF EXISTS instance_questions_points(bigint,double precision); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_points( IN instance_question_id bigint, IN submission_score DOUBLE PRECISION, diff --git a/sprocs/instance_questions_points_exam.sql b/sprocs/instance_questions_points_exam.sql index 56dc953b202..7cd50a382a5 100644 --- a/sprocs/instance_questions_points_exam.sql +++ b/sprocs/instance_questions_points_exam.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_points_exam(bigint,boolean); -DROP FUNCTION IF EXISTS instance_questions_points_exam(bigint,double precision); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_points_exam( IN instance_question_id bigint, IN submission_score DOUBLE PRECISION, diff --git a/sprocs/instance_questions_points_homework.sql b/sprocs/instance_questions_points_homework.sql index cdffbabd2d9..d9e224cae84 100644 --- a/sprocs/instance_questions_points_homework.sql +++ b/sprocs/instance_questions_points_homework.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_points_homework(bigint,boolean); -DROP FUNCTION IF EXISTS instance_questions_points_homework(bigint,double precision); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_points_homework( IN instance_question_id bigint, IN submission_score DOUBLE PRECISION, diff --git a/sprocs/instance_questions_select_question.sql b/sprocs/instance_questions_select_question.sql index 9349a6f387e..b5cb28000f2 100644 --- a/sprocs/instance_questions_select_question.sql +++ b/sprocs/instance_questions_select_question.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_select_question(bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_select_question ( IN instance_question_id bigint, OUT question questions diff --git a/sprocs/instance_questions_select_variant.sql b/sprocs/instance_questions_select_variant.sql index 4e5e5fa55c9..0b781a9f9fb 100644 --- a/sprocs/instance_questions_select_variant.sql +++ b/sprocs/instance_questions_select_variant.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_select_variant(bigint, boolean); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_select_variant ( IN instance_question_id bigint, IN require_open boolean, diff --git a/sprocs/instance_questions_update_in_grading.sql b/sprocs/instance_questions_update_in_grading.sql index ffee51e40b0..42b7575e8a6 100644 --- a/sprocs/instance_questions_update_in_grading.sql +++ b/sprocs/instance_questions_update_in_grading.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_update_in_grading ( instance_question_id bigint, authn_user_id bigint diff --git a/sprocs/instance_questions_update_score.sql b/sprocs/instance_questions_update_score.sql index 24f9795db75..8086b41fb80 100644 --- a/sprocs/instance_questions_update_score.sql +++ b/sprocs/instance_questions_update_score.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS instance_questions_update_score(bigint,bigint,bigint,bigint,text,integer,text,double precision,double precision,jsonb,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION instance_questions_update_score( -- identify the assessment/assessment_instance IN arg_assessment_id bigint, -- must provide assessment_id diff --git a/sprocs/interval_hist_thresholds.sql b/sprocs/interval_hist_thresholds.sql index 0f614e9f251..04510d0fe83 100644 --- a/sprocs/interval_hist_thresholds.sql +++ b/sprocs/interval_hist_thresholds.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION interval_hist_thresholds (duration INTERVAL) RETURNS INTERVAL[] AS $$ WITH candidates AS ( SELECT @@ -46,13 +46,13 @@ CREATE OR REPLACE FUNCTION generate_series(0, num_steps) AS i $$ LANGUAGE SQL IMMUTABLE; -CREATE OR REPLACE FUNCTION +CREATE FUNCTION interval_array_to_seconds (durations INTERVAL[]) RETURNS DOUBLE PRECISION[] AS $$ SELECT array_agg(EXTRACT(EPOCH FROM d)) FROM unnest(durations) AS vals (d) $$ LANGUAGE SQL IMMUTABLE; -CREATE OR REPLACE FUNCTION +CREATE FUNCTION interval_array_to_strings (durations INTERVAL[]) RETURNS TEXT[] AS $$ SELECT array_agg(format_interval_short(d)) FROM unnest(durations) AS vals (d) diff --git a/sprocs/ip_to_mode.sql b/sprocs/ip_to_mode.sql index 9005e1eb8d6..c4de46c9b77 100644 --- a/sprocs/ip_to_mode.sql +++ b/sprocs/ip_to_mode.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS ip_to_mode(inet,timestamptz); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION ip_to_mode( IN ip inet, IN date timestamptz, diff --git a/sprocs/issues_insert_for_assessment.sql b/sprocs/issues_insert_for_assessment.sql index 73685ebe9af..467267cf2d8 100644 --- a/sprocs/issues_insert_for_assessment.sql +++ b/sprocs/issues_insert_for_assessment.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS issues_insert_for_assessment(bigint,text,text,boolean,jsonb,jsonb,bigint,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION issues_insert_for_assessment( assessment_id bigint, student_message text, diff --git a/sprocs/issues_insert_for_variant.sql b/sprocs/issues_insert_for_variant.sql index 636e449c1ef..30270096df2 100644 --- a/sprocs/issues_insert_for_variant.sql +++ b/sprocs/issues_insert_for_variant.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS issues_insert_for_variant(bigint,text,boolean,jsonb,jsonb,bigint); -DROP FUNCTION IF EXISTS issues_insert_for_variant(bigint,text,boolean,boolean,jsonb,jsonb,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION issues_insert_for_variant( variant_id bigint, student_message text, diff --git a/sprocs/issues_select_with_filter.sql b/sprocs/issues_select_with_filter.sql index 601d8e378c5..330af0c7a90 100644 --- a/sprocs/issues_select_with_filter.sql +++ b/sprocs/issues_select_with_filter.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS issues_select_with_filter (boolean,boolean,boolean,text[],text[],text[],text[],text); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION issues_select_with_filter ( filter_is_open boolean, filter_is_closed boolean, diff --git a/sprocs/issues_update_open.sql b/sprocs/issues_update_open.sql index e954a3f8494..510689437ce 100644 --- a/sprocs/issues_update_open.sql +++ b/sprocs/issues_update_open.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION issues_update_open ( issue_id bigint, new_open boolean, diff --git a/sprocs/issues_update_open_all.sql b/sprocs/issues_update_open_all.sql index 78e133a0713..7dcb6c2656c 100644 --- a/sprocs/issues_update_open_all.sql +++ b/sprocs/issues_update_open_all.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION issues_update_open_all ( new_open boolean, course_id bigint, diff --git a/sprocs/jsonb_array_to_double_precision_array.sql b/sprocs/jsonb_array_to_double_precision_array.sql index 9169848e9b2..985b28a2db9 100644 --- a/sprocs/jsonb_array_to_double_precision_array.sql +++ b/sprocs/jsonb_array_to_double_precision_array.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS jsonb_array_to_double_precision_array(jsonb); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION jsonb_array_to_double_precision_array( IN jsonb_array jsonb ) RETURNS double precision[] diff --git a/sprocs/jsonb_array_to_text_array.sql b/sprocs/jsonb_array_to_text_array.sql index 8c521694208..60d41d1c5c0 100644 --- a/sprocs/jsonb_array_to_text_array.sql +++ b/sprocs/jsonb_array_to_text_array.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS jsonb_array_to_text_array(jsonb); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION jsonb_array_to_text_array( IN jsonb_array jsonb ) RETURNS text[] diff --git a/sprocs/last.sql b/sprocs/last.sql index ffda16931da..3103cefd1d9 100644 --- a/sprocs/last.sql +++ b/sprocs/last.sql @@ -1,12 +1,12 @@ -- Create a function that always returns the last non-NULL item -CREATE OR REPLACE FUNCTION public.last_agg ( anyelement, anyelement ) +CREATE FUNCTION last_agg ( anyelement, anyelement ) RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$ SELECT $2; $$; -- And then wrap an aggregate around it -CREATE AGGREGATE public.LAST ( - sfunc = public.last_agg, +CREATE AGGREGATE LAST ( + sfunc = last_agg, basetype = anyelement, stype = anyelement -); \ No newline at end of file +); diff --git a/sprocs/lock_timeout_set.sql b/sprocs/lock_timeout_set.sql index d2bc13c736a..8e1db726971 100644 --- a/sprocs/lock_timeout_set.sql +++ b/sprocs/lock_timeout_set.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION lock_timeout_set( timeout integer ) RETURNS void diff --git a/sprocs/question_order.sql b/sprocs/question_order.sql index dab6ac1ab8b..badb5cc4d20 100644 --- a/sprocs/question_order.sql +++ b/sprocs/question_order.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS question_order(bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION question_order ( assessment_instance_id BIGINT ) RETURNS TABLE (instance_question_id BIGINT, row_order INTEGER, question_number TEXT) diff --git a/sprocs/questions_select.sql b/sprocs/questions_select.sql index 4d99b1358d0..c19954499f9 100644 --- a/sprocs/questions_select.sql +++ b/sprocs/questions_select.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION questions_select ( IN question_id bigint, OUT question questions diff --git a/sprocs/random_string.sql b/sprocs/random_string.sql deleted file mode 100644 index 16e07c972a0..00000000000 --- a/sprocs/random_string.sql +++ /dev/null @@ -1,19 +0,0 @@ --- a random string generator for a 4-character join code suffix -CREATE OR REPLACE FUNCTION - random_string( - IN string_length INTEGER, - IN possible_chars TEXT DEFAULT '0123456789' - ) RETURNS text -AS $$ -DECLARE - output TEXT = ''; - i INT4; - pos INT4; -BEGIN - FOR i IN 1..string_length LOOP - pos := 1 + CAST( random() * ( LENGTH(possible_chars) - 1) AS INT4 ); - output := output || substr(possible_chars, pos, 1); - END LOOP; - RETURN output; -END; -$$ LANGUAGE plpgsql IMMUTABLE; diff --git a/sprocs/random_unique.sql b/sprocs/random_unique.sql index 1437e1424d8..b4cbcb3aa0f 100644 --- a/sprocs/random_unique.sql +++ b/sprocs/random_unique.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION random_unique( lower INTEGER, upper INTEGER, -- may expand range if needed, so true upper bound might be higher than this diff --git a/sprocs/select_assessment_questions.sql b/sprocs/select_assessment_questions.sql index c6d401a6fa6..5131c18ad9e 100644 --- a/sprocs/select_assessment_questions.sql +++ b/sprocs/select_assessment_questions.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS select_assessment_questions(bigint); -DROP FUNCTION IF EXISTS select_assessment_questions(bigint,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION select_assessment_questions( assessment_id bigint, assessment_instance_id bigint DEFAULT NULL -- if provided, an existing assessment instance diff --git a/sprocs/select_or_insert_course_by_path.sql b/sprocs/select_or_insert_course_by_path.sql index 0f8bb004014..411b7d5ee5c 100644 --- a/sprocs/select_or_insert_course_by_path.sql +++ b/sprocs/select_or_insert_course_by_path.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION select_or_insert_course_by_path( IN path text, OUT course_id bigint diff --git a/sprocs/server_loads_current.sql b/sprocs/server_loads_current.sql index 6b39af947a7..2d4c2506660 100644 --- a/sprocs/server_loads_current.sql +++ b/sprocs/server_loads_current.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS server_loads_current(text,interval); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION server_loads_current ( IN group_name text, IN current_interval interval diff --git a/sprocs/server_usage_current.sql b/sprocs/server_usage_current.sql index 826db60fe66..514d4382b66 100644 --- a/sprocs/server_usage_current.sql +++ b/sprocs/server_usage_current.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS server_usage_current(interval); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION server_usage_current ( IN current_interval interval, OUT user_count integer, diff --git a/sprocs/submissions_insert.sql b/sprocs/submissions_insert.sql index a3a7bdb8045..da1e6abfc0f 100644 --- a/sprocs/submissions_insert.sql +++ b/sprocs/submissions_insert.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS submissions_insert(jsonb,jsonb,jsonb,boolean,integer,enum_mode,bigint,bigint,bigint); -DROP FUNCTION IF EXISTS submissions_insert(jsonb,jsonb,jsonb,boolean,boolean,integer,enum_mode,bigint,bigint,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION submissions_insert( IN submitted_answer jsonb, IN raw_submitted_answer jsonb, diff --git a/sprocs/submissions_lock.sql b/sprocs/submissions_lock.sql index 81cd4cc3fb3..e533f6e3853 100644 --- a/sprocs/submissions_lock.sql +++ b/sprocs/submissions_lock.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION submissions_lock ( submission_id bigint ) RETURNS void diff --git a/sprocs/submissions_select.sql b/sprocs/submissions_select.sql index 2d196bdcbb0..04551a21681 100644 --- a/sprocs/submissions_select.sql +++ b/sprocs/submissions_select.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION submissions_select ( IN submission_id bigint, OUT submission submissions diff --git a/sprocs/submissions_update_parsing.sql b/sprocs/submissions_update_parsing.sql index 54dff3f4798..aba489e2828 100644 --- a/sprocs/submissions_update_parsing.sql +++ b/sprocs/submissions_update_parsing.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS submissions_update_parsing(bigint,jsonb,jsonb); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION submissions_update_parsing( submission_id bigint, submitted_answer jsonb, diff --git a/sprocs/sync_assessment_sets.sql b/sprocs/sync_assessment_sets.sql index d79e727635d..c822859455b 100644 --- a/sprocs/sync_assessment_sets.sql +++ b/sprocs/sync_assessment_sets.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS sync_assessment_sets(JSONB, bigint); -DROP FUNCTION IF EXISTS sync_assessment_sets(boolean, jsonb, text[], bigint); -DROP FUNCTION IF EXISTS sync_assessment_sets(boolean, boolean, jsonb, text[], bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_assessment_sets( IN valid_course_info boolean, IN delete_unused boolean, diff --git a/sprocs/sync_assessments.sql b/sprocs/sync_assessments.sql index 55c66de4991..e2eb1314995 100644 --- a/sprocs/sync_assessments.sql +++ b/sprocs/sync_assessments.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS sync_assessments(JSONB, bigint, bigint, boolean); -DROP FUNCTION IF EXISTS sync_assessments(JSONB[], bigint, bigint, boolean); -DROP FUNCTION IF EXISTS sync_assessments(JSONB[], bigint, bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_assessments( IN disk_assessments_data JSONB[], IN syncing_course_id bigint, diff --git a/sprocs/sync_course_instances.sql b/sprocs/sync_course_instances.sql index 64adf036255..f11212dd0b7 100644 --- a/sprocs/sync_course_instances.sql +++ b/sprocs/sync_course_instances.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS sync_course_instances(JSONB, bigint); -DROP FUNCTION IF EXISTS sync_course_instances(JSONB[], bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_course_instances( IN disk_course_instances_data JSONB[], IN syncing_course_id bigint, diff --git a/sprocs/sync_course_tags.sql b/sprocs/sync_course_tags.sql index 9974756a8c1..000c88c4c69 100644 --- a/sprocs/sync_course_tags.sql +++ b/sprocs/sync_course_tags.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS sync_course_tags(JSONB, bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_course_tags( IN valid_course_info boolean, IN delete_unused boolean, diff --git a/sprocs/sync_news_items.sql b/sprocs/sync_news_items.sql index 72c874cb74b..dad7b10d726 100644 --- a/sprocs/sync_news_items.sql +++ b/sprocs/sync_news_items.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS sync_news_items(jsonb); -DROP FUNCTION IF EXISTS sync_news_items(jsonb,boolean); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_news_items ( IN news_items_on_disk jsonb, IN notify_with_new_server boolean -- should we send notifications on a new server install (a blank DB) diff --git a/sprocs/sync_question_tags.sql b/sprocs/sync_question_tags.sql index 16ab9493dc9..d8818ae1285 100644 --- a/sprocs/sync_question_tags.sql +++ b/sprocs/sync_question_tags.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS sync_question_tags(JSONB); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_question_tags( IN new_question_tags JSONB[] ) RETURNS void diff --git a/sprocs/sync_questions.sql b/sprocs/sync_questions.sql index 134bbd802c0..8ca07e9567d 100644 --- a/sprocs/sync_questions.sql +++ b/sprocs/sync_questions.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS sync_questions(JSONB, bigint); -DROP FUNCTION IF EXISTS sync_questions(JSONB[], bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_questions( IN disk_questions_data JSONB[], IN syncing_course_id bigint, diff --git a/sprocs/sync_topics.sql b/sprocs/sync_topics.sql index 3eb316a6b93..bd4c65e68fd 100644 --- a/sprocs/sync_topics.sql +++ b/sprocs/sync_topics.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS sync_topics(JSONB, bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION sync_topics( IN valid_course_info boolean, IN delete_unused boolean, diff --git a/sprocs/tags_for_question.sql b/sprocs/tags_for_question.sql index a5f19dc06a1..88f406ba926 100644 --- a/sprocs/tags_for_question.sql +++ b/sprocs/tags_for_question.sql @@ -1,7 +1,6 @@ - -- Returns a JSON array describing the tags for question question_id. -CREATE OR REPLACE FUNCTION +CREATE FUNCTION tags_for_question (question_id bigint) RETURNS JSONB AS $$ SELECT JSONB_AGG(JSONB_BUILD_OBJECT( diff --git a/sprocs/users_is_course_staff.sql b/sprocs/users_is_course_staff.sql index 61564ed1382..37c05c9fe1d 100644 --- a/sprocs/users_is_course_staff.sql +++ b/sprocs/users_is_course_staff.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS users_is_course_staff(bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION users_is_course_staff ( IN user_id bigint, OUT is_course_staff boolean diff --git a/sprocs/users_randomly_generate.sql b/sprocs/users_randomly_generate.sql index 30b678109bd..e0cbfe076e0 100644 --- a/sprocs/users_randomly_generate.sql +++ b/sprocs/users_randomly_generate.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS users_randomly_generate(int, bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION users_randomly_generate( count int, course_instance_id bigint DEFAULT NULL diff --git a/sprocs/users_select_or_insert.sql b/sprocs/users_select_or_insert.sql index 4f152ada77a..9863714f6cb 100644 --- a/sprocs/users_select_or_insert.sql +++ b/sprocs/users_select_or_insert.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS users_select_or_insert(text, text, text, text); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION users_select_or_insert( IN uid text, IN name text, diff --git a/sprocs/users_select_or_insert_lti.sql b/sprocs/users_select_or_insert_lti.sql index 985d6a7a80e..11666acb297 100644 --- a/sprocs/users_select_or_insert_lti.sql +++ b/sprocs/users_select_or_insert_lti.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION users_select_or_insert_lti( IN uid text, IN name text, diff --git a/sprocs/variants_ensure_instance_question.sql b/sprocs/variants_ensure_instance_question.sql index 986ec3380df..22d197aa1a9 100644 --- a/sprocs/variants_ensure_instance_question.sql +++ b/sprocs/variants_ensure_instance_question.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_ensure_instance_question( IN variant_id bigint, IN instance_question_id bigint, diff --git a/sprocs/variants_ensure_open.sql b/sprocs/variants_ensure_open.sql index c9105694efe..4f8def96d41 100644 --- a/sprocs/variants_ensure_open.sql +++ b/sprocs/variants_ensure_open.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_ensure_open ( variant_id bigint ) RETURNS void diff --git a/sprocs/variants_ensure_question.sql b/sprocs/variants_ensure_question.sql index 80d3d0ffeb3..f785e7641df 100644 --- a/sprocs/variants_ensure_question.sql +++ b/sprocs/variants_ensure_question.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_ensure_question( IN variant_id bigint, IN question_id bigint, diff --git a/sprocs/variants_insert.sql b/sprocs/variants_insert.sql index ba9794196e6..acb8ff7cdf5 100644 --- a/sprocs/variants_insert.sql +++ b/sprocs/variants_insert.sql @@ -1,8 +1,4 @@ -DROP FUNCTION IF EXISTS variants_insert(text,jsonb,jsonb,jsonb,boolean,bigint,bigint,bigint,bigint); -DROP FUNCTION IF EXISTS variants_insert(text,jsonb,jsonb,jsonb,boolean,bigint,bigint,bigint,bigint,bigint); -DROP FUNCTION IF EXISTS variants_insert(text,jsonb,jsonb,jsonb,boolean,bigint,bigint,bigint,bigint,bigint, boolean); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_insert( IN variant_seed text, IN params jsonb, diff --git a/sprocs/variants_lock.sql b/sprocs/variants_lock.sql index 32645553576..a72767f28cf 100644 --- a/sprocs/variants_lock.sql +++ b/sprocs/variants_lock.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_lock ( variant_id bigint ) RETURNS void diff --git a/sprocs/variants_select.sql b/sprocs/variants_select.sql index 76d9a6889ed..503ffa63028 100644 --- a/sprocs/variants_select.sql +++ b/sprocs/variants_select.sql @@ -1,5 +1,4 @@ -DROP FUNCTION IF EXISTS variants_select(bigint); -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_select ( IN variant_id bigint, OUT variant jsonb diff --git a/sprocs/variants_select_for_assessment_instance_grading.sql b/sprocs/variants_select_for_assessment_instance_grading.sql index 20b0a02a31a..9abbc4c0783 100644 --- a/sprocs/variants_select_for_assessment_instance_grading.sql +++ b/sprocs/variants_select_for_assessment_instance_grading.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS variants_select_for_assessment_instance(bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_select_for_assessment_instance_grading ( IN assessment_instance_id bigint, OUT variant jsonb, diff --git a/sprocs/variants_select_submission_for_grading.sql b/sprocs/variants_select_submission_for_grading.sql index b7b0be1597e..598e5bf89f2 100644 --- a/sprocs/variants_select_submission_for_grading.sql +++ b/sprocs/variants_select_submission_for_grading.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS variants_select_submission_for_grading(bigint,boolean); -DROP FUNCTION IF EXISTS variants_select_submission_for_grading(bigint,bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_select_submission_for_grading ( IN variant_id bigint, IN check_submission_id bigint DEFAULT NULL diff --git a/sprocs/variants_unlink.sql b/sprocs/variants_unlink.sql index 632ee3c8629..9f3d59b0cfd 100644 --- a/sprocs/variants_unlink.sql +++ b/sprocs/variants_unlink.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS variants_unlink(bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_unlink( variant_id bigint ) RETURNS void diff --git a/sprocs/variants_update_after_grading.sql b/sprocs/variants_update_after_grading.sql index 53eaf88b286..ed87109463e 100644 --- a/sprocs/variants_update_after_grading.sql +++ b/sprocs/variants_update_after_grading.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS variants_update_after_grading(bigint); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION variants_update_after_grading( variant_id bigint, correct boolean diff --git a/sprocs/workspace_hosts_assign_workspace.sql b/sprocs/workspace_hosts_assign_workspace.sql index 6e3712b0e8d..985a9543d13 100644 --- a/sprocs/workspace_hosts_assign_workspace.sql +++ b/sprocs/workspace_hosts_assign_workspace.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS workspace_hosts_assign_workspace(bigint, integer); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION workspace_hosts_assign_workspace( IN workspace_id bigint, IN capacity integer, diff --git a/sprocs/workspace_hosts_drain_extra.sql b/sprocs/workspace_hosts_drain_extra.sql index ca988bc6504..d646193edda 100644 --- a/sprocs/workspace_hosts_drain_extra.sql +++ b/sprocs/workspace_hosts_drain_extra.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION workspace_hosts_drain_extra(surplus integer) RETURNS void AS $$ BEGIN diff --git a/sprocs/workspace_hosts_find_terminable.sql b/sprocs/workspace_hosts_find_terminable.sql index a34b125bfed..33f94a7796c 100644 --- a/sprocs/workspace_hosts_find_terminable.sql +++ b/sprocs/workspace_hosts_find_terminable.sql @@ -1,6 +1,4 @@ -DROP FUNCTION IF EXISTS workspace_hosts_find_terminable(integer, integer); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION workspace_hosts_find_terminable( IN unhealthy_timeout_sec integer, IN launch_timeout_sec integer, diff --git a/sprocs/workspace_hosts_recapture_draining.sql b/sprocs/workspace_hosts_recapture_draining.sql index 72f6da0fe9b..6901aae2c7a 100644 --- a/sprocs/workspace_hosts_recapture_draining.sql +++ b/sprocs/workspace_hosts_recapture_draining.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION workspace_hosts_recapture_draining( IN needed_hosts integer, OUT recaptured_hosts integer diff --git a/sprocs/workspace_loads_current.sql b/sprocs/workspace_loads_current.sql index b8f59ec2d8e..7313a41e3b8 100644 --- a/sprocs/workspace_loads_current.sql +++ b/sprocs/workspace_loads_current.sql @@ -1,5 +1,3 @@ -DROP FUNCTION IF EXISTS workspace_loads_current(double precision, double precision); - CREATE FUNCTION workspace_loads_current( IN workspace_capacity_factor double precision, diff --git a/sprocs/workspaces_message_update.sql b/sprocs/workspaces_message_update.sql index 6fc588ffac8..266a9f96dcc 100644 --- a/sprocs/workspaces_message_update.sql +++ b/sprocs/workspaces_message_update.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION +CREATE FUNCTION workspaces_message_update( workspace_id bigint, workspace_message text diff --git a/sprocs/workspaces_state_update.sql b/sprocs/workspaces_state_update.sql index 6a55d79a640..a8e65276c81 100644 --- a/sprocs/workspaces_state_update.sql +++ b/sprocs/workspaces_state_update.sql @@ -1,7 +1,4 @@ -DROP FUNCTION IF EXISTS workspaces_state_update(bigint, text); -DROP FUNCTION IF EXISTS workspaces_state_update(bigint, enum_workspace_state, text); - -CREATE OR REPLACE FUNCTION +CREATE FUNCTION workspaces_state_update( workspace_id bigint, workspace_state enum_workspace_state, diff --git a/tests/helperDb.js b/tests/helperDb.js index 4ac80a36f61..f6910283a93 100644 --- a/tests/helperDb.js +++ b/tests/helperDb.js @@ -77,6 +77,12 @@ var createFullDatabase = function(dbName, dropFirst, mochaThis, callback) { callback(null); }); }, + function(callback) { + sqldb.setRandomSearchSchema('test', (err) => { + if (ERR(err, callback)) return; + callback(null); + }); + }, function(callback) { debug('createFullDatabase(): initializing sprocs'); sprocs.init(function(err) {