--- /dev/null
+
+= Short tutorial =
+
+This section explains how to use PL/Proxy to proxy queries for a users email
+address across a set of remote databases. For purposes of this intro we assume
+each remote database has a users table that contains a username and email column.
+
+We also assume that the data is paritioned across remote databases by taking
+a hash of the username and assigning it to one of 2 servers. Real applications
+should use a partitioning scheme that is approriate to their requirments.
+
+For the purposes of this example assume that the partition databases plproxy_1
+and plproxy_2 both contain a table resembling
+
+ CREATE TABLE user ("user" text,email text);
+
+PL/Proxy is installed on the proxy database.
+
+
+== Simple remote function call ==
+
+Here we will create a plproxy function that connects to the database named
+'plproxy_1' and returns a users email address.
+
+Connect to `dbname=plproxy_1` and run following SQL there: `SELECT * from get_user_email($1);`
+
+
+ CREATE FUNCTION get_user_email(username text)
+ RETURNS text AS $$
+ CONNECT 'dbname=plproxy_1';
+ SELECT email FROM users WHERE user = $1;
+ $$ LANGUAGE plproxy;
+
+The above example uses plproxy to proxy the query to the remote datababase but
+performs no partitioning. It assumes that the entire users table is in the
+remote users database. The next few steps will describe how to partition data
+with PL/Proxy.
+
+
+== Create a configuration functions ==
+
+Using PL/Proxy for partitioning requires setting up some configuration functions.
+
+When a query needs to be forwarded to a remote database the function
+plproxy.get_cluster_partitions(cluster) is invoked by plproxy to get the
+connection string to use for each partition.
+
+The following is an example
+
+ CREATE OR REPLACE FUNCTION plproxy.get_cluster_partitions(cluster_name text)
+ RETURNS SETOF text AS $$
+ VALUES ( 'host=localhost dbname=plproxy_1'),
+ ( 'host=localhost dbname=plproxy_2')
+ $$ LANGUAGE SQL
+
+A production application might query some configuration tables to return the
+connstrings. The number of partitions must be a power of 2.
+
+Next define a plproxy.get_cluster_version(cluster_name) function. This is
+called on each request and determines if the output from a cached
+result from plproxy.get_cluster_partitions can be reused.
+
+ CREATE FUNCTION plproxy.get_cluster_version(cluster_name text)
+ RETURNS integer AS $$
+ SELECT 1;
+ $$ LANGUAGE SQL
+
+We also need to provide a plproxy.get_cluster_config function. Ours will provide
+nothing. See the configuration section for details on what this function can do.
+
+
+ CREATE OR REPLACE FUNCTION plproxy.get_cluster_config(in cluster_name text, out key text, out val text)
+ RETURNS SETOF record AS $$
+ SELECT 'connection_lifetime'::text AS key, '0'::text as val;
+ $$ LANGUAGE SQL;
+
+See config.txt for a more detailed desciption of the above functions.
+
+
+== Partitioned remote call ==
+
+Here we assume that the users table is spread over several databases based
+a hash of the users name. The connection string for these databases is
+contained in the get_cluster_partitions function described above.
+
+Below is a get_user_email function that when execute on the proxy server,
+a remote connection to the approriate partitioned database will be made and
+the users email address will be returned.
+
+ CREATE OR REPLACE FUNCTION get_user_email(username text)
+ RETURNS text AS $$
+ CLUSTER 'userdb';
+ RUN ON hashtext(username) ;
+ SELECT email FROM users WHERE "user" = $1;
+ $$ LANGUAGE plproxy;
+
+== Inserting into the proper partition ==
+
+Next we provide a simple INSERT function.
+
+We define this function on both plproxy_1 and plproxy_2
+
+ CREATE OR REPLACE FUNCTION insert_user(username text, emailaddress text)
+ RETURNS integer AS $$
+ INSERT INTO users ("user",email) VALUES ($1,$2);
+ SELECT 1;
+ $$ LANGUAGE SQL;
+
+Now we define a proxy function in the proxy database to send the
+INSERT's to the approriate target.
+
+
+ CREATE OR REPLACE FUNCTION insert_user(username text, emailaddress text)
+ RETURNS integer AS $$
+ CLUSTER 'userdb';
+ RUN ON hashtext(username);
+ $$ LANGUAGE plproxy;
+
+
+== Putting it all together ==
+
+Connect to the proxy database (The one we installed plproxy and the plproxy
+functions on).
+
+ SELECT insert_user('Sven','sven@somewhere.com');
+ SELECT insert_user('Marko', 'marko@somewhere.com');
+ SELECT insert_user('Steve','steve@somewhere.cm');
+
+Now connect to the plproxy_1 and plproxy_2 databases. Sven and Marko should be
+in plproxy_2 , and Steve should be in plproxy_1.
+
+When connected to the proxy user you can obtain data by doing
+
+ SELECT get_user_email('Sven');
+ SELECT get_user_email('Marko');
+ SELECT get_user_email('Steve');
+