diff --git a/modules/system/system.install b/modules/system/system.install
index 758b4a17d5a87b42073ca4757235ccb7b8d6efa5..c48c960175b05ea675b92c86bb92828756da066d 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -550,6 +550,38 @@ function system_install() {
       db_query("CREATE DOMAIN smallint_unsigned smallint CHECK (VALUE >= 0)");
       db_query("CREATE DOMAIN bigint_unsigned bigint CHECK (VALUE >= 0)");
 
+      /* create functions */
+      db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric) RETURNS numeric AS
+        \'SELECT CASE WHEN (($1 > $2) OR ($2 IS NULL)) THEN $1 ELSE $2 END;\'
+        LANGUAGE \'sql\''
+      );
+      db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric, numeric) RETURNS numeric AS
+        \'SELECT greatest($1, greatest($2, $3));\'
+        LANGUAGE \'sql\''
+      );
+      if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname = 'concat'"))) {
+        db_query('CREATE OR REPLACE FUNCTION "rand"() RETURNS float AS
+          \'SELECT random();\'
+          LANGUAGE \'sql\''
+        );
+      }
+
+      if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname = 'concat'"))) {
+        db_query('CREATE OR REPLACE FUNCTION "concat"(text, text) RETURNS text AS
+          \'SELECT $1 || $2;\'
+          LANGUAGE \'sql\''
+        );
+      }
+      db_query('CREATE OR REPLACE FUNCTION "if"(boolean, text, text) RETURNS text AS
+        \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
+        LANGUAGE \'sql\''
+      );
+      db_query('CREATE OR REPLACE FUNCTION "if"(boolean, integer, integer) RETURNS integer AS
+        \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
+        LANGUAGE \'sql\''
+      );
+
+      /* create tables */
       db_query("CREATE TABLE {access} (
         aid serial,
         mask varchar(255) NOT NULL default '',