mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-03-11 18:01:23 +00:00
Monotone-Revision: 9054022ef1ca8aeba6e34842d27d9b94ce002b89 Monotone-Author: dev-unix.inverse.qc.ca Monotone-Date: 2006-06-15T19:34:10 Monotone-Branch: ca.inverse.sogo
206 lines
7.3 KiB
Python
Executable File
206 lines
7.3 KiB
Python
Executable File
# func.py - demonstrate the use of SQL functions
|
|
# inspired from the PostgreSQL tutorial
|
|
# adapted to Python 1995 by Pascal ANDRE
|
|
|
|
print """
|
|
__________________________________________________________________
|
|
MODULE FUNC.PY : SQL FUNCTION DEFINITION TUTORIAL
|
|
|
|
This module is designed for being imported from python prompt
|
|
|
|
In order to run the samples included here, first create a connection
|
|
using : cnx = func.DB(...)
|
|
|
|
The "..." should be replaced with whatever arguments you need to open an
|
|
existing database. Usually all you need is the name of the database and,
|
|
in fact, if it is the same as your login name, you can leave it empty.
|
|
|
|
then start the demo with: func.demo(cnx)
|
|
__________________________________________________________________
|
|
"""
|
|
|
|
from pg import DB
|
|
import sys
|
|
|
|
# waits for a key
|
|
def wait_key():
|
|
print "Press <enter>"
|
|
sys.stdin.read(1)
|
|
|
|
# basic functions declaration
|
|
def base_func(pgcnx):
|
|
print "-----------------------------"
|
|
print "-- Creating SQL Functions on Base Types"
|
|
print "-- a CREATE FUNCTION statement lets you create a new "
|
|
print "-- function that can be used in expressions (in SELECT, "
|
|
print "-- INSERT, etc.). We will start with functions that "
|
|
print "-- return values of base types."
|
|
print "-----------------------------"
|
|
print
|
|
print "--"
|
|
print "-- let's create a simple SQL function that takes no arguments"
|
|
print "-- and returns 1"
|
|
print
|
|
print "CREATE FUNCTION one() RETURNS int4"
|
|
print " AS 'SELECT 1 as ONE' LANGUAGE 'sql'"
|
|
pgcnx.query("""CREATE FUNCTION one() RETURNS int4
|
|
AS 'SELECT 1 as ONE' LANGUAGE 'sql'""")
|
|
wait_key()
|
|
print
|
|
print "--"
|
|
print "-- functions can be used in any expressions (eg. in the target"
|
|
print "-- list or qualifications)"
|
|
print
|
|
print "SELECT one() AS answer"
|
|
print pgcnx.query("SELECT one() AS answer")
|
|
print
|
|
print "--"
|
|
print "-- here's how you create a function that takes arguments. The"
|
|
print "-- following function returns the sum of its two arguments:"
|
|
print
|
|
print "CREATE FUNCTION add_em(int4, int4) RETURNS int4"
|
|
print " AS 'SELECT $1 + $2' LANGUAGE 'sql'"
|
|
pgcnx.query("""CREATE FUNCTION add_em(int4, int4) RETURNS int4
|
|
AS 'SELECT $1 + $2' LANGUAGE 'sql'""")
|
|
print
|
|
print "SELECT add_em(1, 2) AS answer"
|
|
print pgcnx.query("SELECT add_em(1, 2) AS answer")
|
|
|
|
# functions on composite types
|
|
def comp_func(pgcnx):
|
|
print "-----------------------------"
|
|
print "-- Creating SQL Functions on Composite Types"
|
|
print "-- it is also possible to create functions that return"
|
|
print "-- values of composite types."
|
|
print "-----------------------------"
|
|
print
|
|
print "-- before we create more sophisticated functions, let's "
|
|
print "-- populate an EMP table"
|
|
print
|
|
print "CREATE TABLE EMP ("
|
|
print " name text,"
|
|
print " salary int4,"
|
|
print " age int4,"
|
|
print " dept varchar(16)"
|
|
print ")"
|
|
pgcnx.query("""CREATE TABLE EMP (
|
|
name text,
|
|
salary int4,
|
|
age int4,
|
|
dept varchar(16))""")
|
|
print
|
|
print "INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')"
|
|
print "INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')"
|
|
print "INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')"
|
|
print "INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')"
|
|
print "INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')"
|
|
pgcnx.query("INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')")
|
|
pgcnx.query("INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')")
|
|
pgcnx.query("INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')")
|
|
pgcnx.query("INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')")
|
|
pgcnx.query("INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')")
|
|
wait_key()
|
|
print
|
|
print "-- the argument of a function can also be a tuple. For "
|
|
print "-- instance, double_salary takes a tuple of the EMP table"
|
|
print
|
|
print "CREATE FUNCTION double_salary(EMP) RETURNS int4"
|
|
print " AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'"
|
|
pgcnx.query("""CREATE FUNCTION double_salary(EMP) RETURNS int4
|
|
AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'""")
|
|
print
|
|
print "SELECT name, double_salary(EMP) AS dream"
|
|
print "FROM EMP"
|
|
print "WHERE EMP.dept = 'toy'"
|
|
print pgcnx.query("""SELECT name, double_salary(EMP) AS dream
|
|
FROM EMP WHERE EMP.dept = 'toy'""")
|
|
print
|
|
print "-- the return value of a function can also be a tuple. However,"
|
|
print "-- make sure that the expressions in the target list is in the "
|
|
print "-- same order as the columns of EMP."
|
|
print
|
|
print "CREATE FUNCTION new_emp() RETURNS EMP"
|
|
print " AS 'SELECT \'None\'::text AS name,"
|
|
print " 1000 AS salary,"
|
|
print " 25 AS age,"
|
|
print " \'none\'::varchar(16) AS dept'"
|
|
print " LANGUAGE 'sql'"
|
|
pgcnx.query("""CREATE FUNCTION new_emp() RETURNS EMP
|
|
AS 'SELECT \\\'None\\\'::text AS name,
|
|
1000 AS salary,
|
|
25 AS age,
|
|
\\\'none\\\'::varchar(16) AS dept'
|
|
LANGUAGE 'sql'""")
|
|
wait_key()
|
|
print
|
|
print "-- you can then project a column out of resulting the tuple by"
|
|
print "-- using the \"function notation\" for projection columns. "
|
|
print "-- (ie. bar(foo) is equivalent to foo.bar) Note that we don't"
|
|
print "-- support new_emp().name at this moment."
|
|
print
|
|
print "SELECT name(new_emp()) AS nobody"
|
|
print pgcnx.query("SELECT name(new_emp()) AS nobody")
|
|
print
|
|
print "-- let's try one more function that returns tuples"
|
|
print "CREATE FUNCTION high_pay() RETURNS setof EMP"
|
|
print " AS 'SELECT * FROM EMP where salary > 1500'"
|
|
print " LANGUAGE 'sql'"
|
|
pgcnx.query("""CREATE FUNCTION high_pay() RETURNS setof EMP
|
|
AS 'SELECT * FROM EMP where salary > 1500'
|
|
LANGUAGE 'sql'""")
|
|
print
|
|
print "SELECT name(high_pay()) AS overpaid"
|
|
print pgcnx.query("SELECT name(high_pay()) AS overpaid")
|
|
|
|
# function with multiple SQL commands
|
|
def mult_func(pgcnx):
|
|
print "-----------------------------"
|
|
print "-- Creating SQL Functions with multiple SQL statements"
|
|
print "-- you can also create functions that do more than just a"
|
|
print "-- SELECT."
|
|
print "-----------------------------"
|
|
print
|
|
print "-- you may have noticed that Andy has a negative salary. We'll"
|
|
print "-- create a function that removes employees with negative "
|
|
print "-- salaries."
|
|
print
|
|
print "SELECT * FROM EMP"
|
|
print pgcnx.query("SELECT * FROM EMP")
|
|
print
|
|
print "CREATE FUNCTION clean_EMP () RETURNS int4"
|
|
print " AS 'DELETE FROM EMP WHERE EMP.salary <= 0"
|
|
print " SELECT 1 AS ignore_this'"
|
|
print " LANGUAGE 'sql'"
|
|
pgcnx.query("CREATE FUNCTION clean_EMP () RETURNS int4 AS 'DELETE FROM EMP WHERE EMP.salary <= 0; SELECT 1 AS ignore_this' LANGUAGE 'sql'")
|
|
print
|
|
print "SELECT clean_EMP()"
|
|
print pgcnx.query("SELECT clean_EMP()")
|
|
print
|
|
print "SELECT * FROM EMP"
|
|
print pgcnx.query("SELECT * FROM EMP")
|
|
|
|
# base cleanup
|
|
def demo_cleanup(pgcnx):
|
|
print "-- remove functions that were created in this file"
|
|
print
|
|
print "DROP FUNCTION clean_EMP()"
|
|
print "DROP FUNCTION high_pay()"
|
|
print "DROP FUNCTION new_emp()"
|
|
print "DROP FUNCTION add_em(int4, int4)"
|
|
print "DROP FUNCTION one()"
|
|
print
|
|
print "DROP TABLE EMP CASCADE"
|
|
pgcnx.query("DROP FUNCTION clean_EMP()")
|
|
pgcnx.query("DROP FUNCTION high_pay()")
|
|
pgcnx.query("DROP FUNCTION new_emp()")
|
|
pgcnx.query("DROP FUNCTION add_em(int4, int4)")
|
|
pgcnx.query("DROP FUNCTION one()")
|
|
pgcnx.query("DROP TABLE EMP CASCADE")
|
|
|
|
# main demo function
|
|
def demo(pgcnx):
|
|
base_func(pgcnx)
|
|
comp_func(pgcnx)
|
|
mult_func(pgcnx)
|
|
demo_cleanup(pgcnx)
|