pg 0.7.9.2008.03.18 → 0.7.9.2008.08.17

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,158 @@
1
+ #
2
+ # Help for query language syntax
3
+ #
4
+ # Original source code is written by C.
5
+ # Copyright (c) 1996, Regents of the University of California
6
+ #
7
+ # ruby version is written by ematsu
8
+ # Copyright (c) 1997 Eiji-usagi-MATSUmoto <ematsu@pfu.co.jp>
9
+ #
10
+ # $Id: psqlHelp.rb,v 1.1.1.2 2002/04/24 05:46:44 noboru Exp $
11
+
12
+
13
+ QL_HELP = [
14
+ [ "abort",
15
+ "abort the current transaction",
16
+ "abort [transaction];"],
17
+ [ "abort transaction",
18
+ "abort the current transaction",
19
+ "abort [transaction];"],
20
+ [ "alter table",
21
+ "add/rename attributes, rename tables",
22
+ "\talter table <class_name> [*] add column <attr> <type>;\n\talter table <class_name> [*] rename [column] <attr1> to <attr2>;\n\talter table <class_name1> rename to <class_name2>"],
23
+ [ "begin",
24
+ "begin a new transaction",
25
+ "begin [transaction|work];"],
26
+ [ "begin transaction",
27
+ "begin a new transaction",
28
+ "begin [transaction|work];"],
29
+ [ "begin work",
30
+ "begin a new transaction",
31
+ "begin [transaction|work];"],
32
+ [ "cluster",
33
+ "create a clustered index (from an existing index)",
34
+ "cluster <index_name> on <relation_name>"],
35
+ [ "close",
36
+ "close an existing cursor (cursor)",
37
+ "close <cursorname>;"],
38
+ [ "commit",
39
+ "commit a transaction",
40
+ "commit [work]"],
41
+ [ "commit work",
42
+ "commit a transaction",
43
+ "commit [work]"],
44
+ [ "copy",
45
+ "copy data to and from a table",
46
+ "copy [binary] <class_name> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"],
47
+ [ "create",
48
+ "Please more be specific:",
49
+ "\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate table\n\tcreate type\n\tcreate view"],
50
+ [ "create aggregate",
51
+ "define an aggregate function",
52
+ "create aggregate <agg_name> [as] (basetype = <data_type>, \n\t[sfunc1 = <sfunc_1>, stype1 = <sfunc1_return_type>]\n\t[sfunc2 = <sfunc_2>, stype2 = <sfunc2_return_type>]\n\t[,finalfunc = <final-function>]\n\t[,initcond1 = <initial-cond1>][,initcond2 = <initial-cond2>]);"],
53
+ [ "create database",
54
+ "create a database",
55
+ "create database <dbname>"],
56
+ [ "create function",
57
+ "create a user-defined function",
58
+ "create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"],
59
+ [ "create index",
60
+ "construct an index",
61
+ "create [unique] index <indexname> on <class_name> [using <access_method>] (<attr1>|<funcname>(<attr1>,...) [<type_class1>]);"],
62
+ [ "create operator",
63
+ "create a user-defined operator",
64
+ "create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"],
65
+ [ "create rule",
66
+ "define a new rule",
67
+ "create rule <rule_name> as on\n\t[select|update|delete|insert]\n\tto <object> [where <qual>]\n\tdo [instead] [<action>|nothing| [<actions>]];"],
68
+ [ "create table",
69
+ "create a new table",
70
+ "create table <class_name> ( <attr1> <type1>,... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"],
71
+ [ "create type",
72
+ "create a new user-defined base data type",
73
+ "create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"],
74
+ [ "create view",
75
+ "create a view",
76
+ "create view <view_name> as select <expr1>[as <attr1>][,... <exprN>[as <attrN>]] [from <from_list>] [where <qual>];"],
77
+ [ "declare",
78
+ "set up a cursor",
79
+ "declare <cursorname> [binary] cursor for\n\tselect [distinct]\n\t<expr1> [as <attr1>],...<exprN> [as <attrN>]\n\t[from <from_list>] [where <qual>]\n\t[order by <attr1> [using <op1>],... <attrN> [using <opN>]];"],
80
+ [ "delete",
81
+ "delete tuples",
82
+ "delete from <class_name> [where <qual>];"],
83
+ [ "drop",
84
+ "Please more be specific:",
85
+ "\tdrop aggregate\n\tdrop database\n\tdrop function\n\tdrop index\n\tdrop operator\n\tdrop rule\n\tdrop table\n\tdrop type\n\tdrop view"],
86
+ [ "drop aggregate",
87
+ "remove an aggregate function",
88
+ "drop aggregate <agg_name>;"],
89
+ [ "drop database",
90
+ "remove a database",
91
+ "drop database <dbname>"],
92
+ [ "drop function",
93
+ "remove a user-defined function",
94
+ "drop function <funcname> ([<type1>,....<typeN>]);"],
95
+ [ "drop index",
96
+ "remove an existing index",
97
+ "drop index <indexname>;"],
98
+ [ "drop operator",
99
+ "remove a user-defined operator",
100
+ "drop operator <operator_name> ([<ltype>|none],[<rtype>|none]);"],
101
+ [ "drop rule",
102
+ "remove a rule",
103
+ "drop rule <rulename>;"],
104
+ [ "drop table",
105
+ "remove a table",
106
+ "drop table <class_name>[,...<class_nameN];"],
107
+ [ "drop type",
108
+ "remove a user-defined base type",
109
+ "drop type <typename>;"],
110
+ [ "drop view",
111
+ "remove a view",
112
+ "drop view <view_name>"],
113
+ [ "end",
114
+ "end the current transaction",
115
+ "end [transaction];"],
116
+ [ "end transaction",
117
+ "end the current transaction",
118
+ "end [transaction];"],
119
+ [ "explain",
120
+ "explain the query execution plan",
121
+ "explain [with {cost|plan|full}] <query>"],
122
+ [ "fetch",
123
+ "retrieve tuples from a cursor",
124
+ "fetch [forward|backward] [<number>|all] [in <cursorname>];"],
125
+ [ "grant",
126
+ "grant access control to a user or group",
127
+ "grant <privilege[,privilege,...]> on <rel1>[,...<reln>] to \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"],
128
+ [ "insert",
129
+ "insert tuples",
130
+ "insert into <class_name> [(<attr1>...<attrN>)]\n\t[values (<expr1>...<exprN>); |\n\tselect <expr1>,...<exprN> [from <from_clause>] [where <qual>];"],
131
+ [ "listen",
132
+ "listen for notification on a relation",
133
+ "listen <class_name>"],
134
+ [ "load",
135
+ "dynamically load a module",
136
+ "load <filename>;"],
137
+ [ "notify",
138
+ "signal all frontends and backends listening on a relation",
139
+ "notify <class_name>"],
140
+ [ "purge",
141
+ "purge historical data",
142
+ "purge <class_name> [before <abstime>] [after <reltime>];"],
143
+ [ "revoke",
144
+ "revoke access control from a user or group",
145
+ "revoke <privilege[,privilege,...]> on <rel1>[,...<reln>] from \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"],
146
+ [ "rollback",
147
+ "abort a transaction",
148
+ "rollback [transaction|work]"],
149
+ [ "select",
150
+ "retrieve tuples",
151
+ "select [distinct on <attr>] <expr1> [as <attr1>], ... <exprN> [as <attrN>]\n\t[into table <class_name>] [from <from_list>]\n\t[where <qual>]\n\t[order by <attr1>\n\t\t[using <op1>],..<attrN> [[using <opN>] | ASC | DESC]];" ],
152
+ [ "update",
153
+ "update tuples",
154
+ "update <class_name> set <attr1>=<expr1>,...<attrN>=<exprN> [from <from_clause>] [where <qual>];"],
155
+ [ "vacuum",
156
+ "vacuum the database, i.e. cleans out deleted records, updates statistics",
157
+ "vacuum [table];"]
158
+ ]
@@ -0,0 +1,63 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # original file src/test/examples/testlibpq.c
4
+ #
5
+ require 'pg'
6
+
7
+ def main
8
+ pghost = nil
9
+ pgport = nil
10
+ pgoptions = nil
11
+ pgtty = nil
12
+ dbname = "template1"
13
+ begin
14
+ conn = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname)
15
+ if $DEBUG
16
+ fd = open("/tmp/trace.out","w")
17
+ conn.trace(fd)
18
+ end
19
+ res = conn.exec("BEGIN")
20
+ res.clear
21
+ res = conn.exec("DECLARE myportal CURSOR FOR select * from pg_database")
22
+ res.clear
23
+
24
+ res = conn.exec("FETCH ALL in myportal")
25
+ if (res.status != PGresult::TUPLES_OK)
26
+ raise PGerror,"FETCH ALL command didn't return tuples properly\n"
27
+ end
28
+
29
+ for fld in res.fields
30
+ printf("%-15s",fld)
31
+ end
32
+ printf("\n\n")
33
+
34
+ res.result.each do |tupl|
35
+ tupl.each do |fld|
36
+ printf("%-15s",fld)
37
+ end
38
+ printf("\n")
39
+ end
40
+ res = conn.exec("CLOSE myportal")
41
+ res = conn.exec("END")
42
+ res.clear
43
+ conn.close
44
+
45
+ if $DEBUG
46
+ fl.close
47
+ end
48
+ rescue PGError
49
+ if (conn.status == PGconn::CONNECTION_BAD)
50
+ printf(STDERR, "We have lost the connection to the backend, so ")
51
+ printf(STDERR, "further processing is impossible. ")
52
+ printf(STDERR, "Terminating.\n")
53
+ else
54
+ printf(STDERR, conn.error)
55
+ end
56
+ exit(1)
57
+ end
58
+ end
59
+
60
+ main
61
+
62
+
63
+
@@ -0,0 +1,44 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # original file src/test/examples/testlibpq2.c
4
+ # Test of the asynchronous notification interface
5
+ # CREATE TABLE TBL1 (i int4);
6
+ # CREATE TABLE TBL2 (i int4);
7
+ # CREATE RULE r1 AS ON INSERT TO TBL1 DO (INSERT INTO TBL2 values (new.i); \
8
+ # NOTIFY TBL2);
9
+ # Then start up this program
10
+ # After the program has begun, do
11
+ # INSERT INTO TBL1 values (10);
12
+
13
+
14
+ require 'pg'
15
+
16
+ def main
17
+ pghost = nil
18
+ pgport = nil
19
+ pgoptions = nil
20
+ pgtty = nil
21
+ dbname = ENV['USER']
22
+ begin
23
+ conn = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname)
24
+ rescue PGError
25
+ printf(STDERR, "Connection to database '%s' failed.\n",dbname)
26
+ exit(2)
27
+ end
28
+ begin
29
+ res = conn.exec("LISTEN TBL2")
30
+ rescue PGError
31
+ printf(STDERR, "LISTEN command failed\n")
32
+ exit(2)
33
+ end
34
+ res.clear
35
+ while 1
36
+ notify = conn.get_notify
37
+ if (notify)
38
+ printf(STDERR,"ASYNC NOTIFY '%s' from backend pid '%d' received\n",notify[0],notify[1])
39
+ break
40
+ end
41
+ end
42
+ end
43
+
44
+ main
@@ -0,0 +1,71 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # original file src/test/examples/testlibpq4.c
4
+ # this test programs shows to use LIBPQ to make multiple backend
5
+ #
6
+ require 'pg'
7
+
8
+ def main
9
+ if (ARGV.size != 4)
10
+ printf(STDERR,"usage: %s tableName dbName1 dbName2\n", ARGV[0])
11
+ printf(STDERR," compares two tables in two databases\n")
12
+ exit(1)
13
+ end
14
+ tblname = ARGV[1]
15
+ dbname1 = ARGV[2]
16
+ dbname2 = ARGV[3]
17
+ pghost = nil
18
+ pgport = nil
19
+ pgoptions = nil
20
+ pgtty = nil
21
+
22
+ begin
23
+ conn1 = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname1)
24
+ conn2 = PGconn.connect(pghost,pgport,pgoptions,pgtty,dbname2)
25
+ rescue PGError
26
+ printf(STDERR,"connection to database.\n")
27
+ exit(1)
28
+ end
29
+ begin
30
+ res1 = conn1.exec("BEGIN")
31
+ res1.clear
32
+ res1 = conn1.exec("DECLARE myportal CURSOR FOR select * from pg_database")
33
+ res1.clear
34
+
35
+ res1 = conn1.exec("FETCH ALL in myportal")
36
+ if (res1.status != PGresult::TUPLES_OK)
37
+ raise PGerror,"FETCH ALL command didn't return tuples properly\n"
38
+ end
39
+
40
+ for fld in res1.fields
41
+ printf("%-15s",fld)
42
+ end
43
+ printf("\n\n")
44
+
45
+ res1.result.each do |tupl|
46
+ tupl.each do |fld|
47
+ printf("%-15s",fld)
48
+ end
49
+ printf("\n")
50
+ end
51
+ res1 = conn1.exec("CLOSE myportal")
52
+ res1 = conn1.exec("END")
53
+ res1.clear
54
+ conn1.close
55
+
56
+ rescue PGError
57
+ if (conn1.status == PGconn::CONNECTION_BAD)
58
+ printf(STDERR, "We have lost the connection to the backend, so ")
59
+ printf(STDERR, "further processing is impossible. ")
60
+ printf(STDERR, "Terminating.\n")
61
+ else
62
+ printf(STDERR, conn1.error)
63
+ end
64
+ exit(1)
65
+ end
66
+ end
67
+
68
+ main
69
+
70
+
71
+
@@ -0,0 +1,26 @@
1
+ To backend> Msg Q
2
+ To backend> "SELECT 1 AS one"
3
+ To backend> Msg complete, length 21
4
+ From backend> T
5
+ From backend (#4)> 28
6
+ From backend (#2)> 1
7
+ From backend> "one"
8
+ From backend (#4)> 0
9
+ From backend (#2)> 0
10
+ From backend (#4)> 23
11
+ From backend (#2)> 4
12
+ From backend (#4)> -1
13
+ From backend (#2)> 0
14
+ From backend> D
15
+ From backend (#4)> 11
16
+ From backend (#2)> 1
17
+ From backend (#4)> 1
18
+ From backend (1)> 1
19
+ From backend> C
20
+ From backend (#4)> 11
21
+ From backend> "SELECT"
22
+ From backend> Z
23
+ From backend (#4)> 5
24
+ From backend> Z
25
+ From backend (#4)> 5
26
+ From backend> I
@@ -0,0 +1,127 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $LOAD_PATH.unshift('ext')
5
+ require 'pg'
6
+
7
+ describe PGconn do
8
+
9
+ before( :all ) do
10
+ puts "====== TESTING PGconn ======"
11
+ @test_directory = "#{Dir.getwd}/tmp_test_#{rand}"
12
+ @test_pgdata = @test_directory + '/data'
13
+ if File.exists?(@test_directory) then
14
+ raise "test directory exists!"
15
+ end
16
+ @conninfo = "host='#{@test_directory}' dbname=test"
17
+ Dir.mkdir(@test_directory)
18
+ Dir.mkdir(@test_pgdata)
19
+ cmds = []
20
+ cmds << "initdb -D '#{@test_pgdata}'"
21
+ cmds << "pg_ctl -D '#{@test_pgdata}' " +
22
+ %!-o "--unix-socket-directory='#{@test_directory}' ! +
23
+ %!--listen-addresses=''" ! +
24
+ "start"
25
+ cmds << "sleep 2"
26
+ cmds << "createdb -h '#{@test_directory}' test"
27
+ cmds.each do |cmd|
28
+ if not system(cmd) then
29
+ raise "Error executing cmd: #{cmd}: #{$?}"
30
+ end
31
+ end
32
+ @conn = PGconn.connect(@conninfo)
33
+ end
34
+
35
+ it "should connect successfully with connection string" do
36
+ tmpconn = PGconn.connect(@conninfo)
37
+ tmpconn.status.should== PGconn::CONNECTION_OK
38
+ tmpconn.finish
39
+ end
40
+
41
+ it "should connect using 7 arguments converted to strings" do
42
+ tmpconn = PGconn.connect(@test_directory, 5432, nil, nil, :test, nil, nil)
43
+ tmpconn.status.should== PGconn::CONNECTION_OK
44
+ tmpconn.finish
45
+ end
46
+
47
+ it "should connect using hash" do
48
+ tmpconn = PGconn.connect(
49
+ :host => @test_directory,
50
+ :port => 5432,
51
+ :dbname => :test)
52
+ tmpconn.status.should== PGconn::CONNECTION_OK
53
+ tmpconn.finish
54
+ end
55
+
56
+ it "should connect asynchronously" do
57
+ tmpconn = PGconn.connect_start(@conninfo)
58
+ socket = IO.for_fd(tmpconn.socket)
59
+ status = tmpconn.connect_poll
60
+ while(status != PGconn::PGRES_POLLING_OK) do
61
+ if(status == PGconn::PGRES_POLLING_READING)
62
+ if(not select([socket],[],[],5.0))
63
+ raise "Asynchronous connection timed out!"
64
+ end
65
+ elsif(status == PGconn::PGRES_POLLING_WRITING)
66
+ if(not select([],[socket],[],5.0))
67
+ raise "Asynchronous connection timed out!"
68
+ end
69
+ end
70
+ status = tmpconn.connect_poll
71
+ end
72
+ tmpconn.status.should== PGconn::CONNECTION_OK
73
+ tmpconn.finish
74
+ end
75
+
76
+ it "should not leave stale server connections after finish" do
77
+ PGconn.connect(@conninfo).finish
78
+ res = @conn.exec(%[SELECT COUNT(*) AS n FROM pg_stat_activity
79
+ WHERE usename IS NOT NULL])
80
+ # there's still the global @conn, but should be no more
81
+ res[0]['n'].should == '1'
82
+ end
83
+
84
+ it "should trace and untrace client-server communication" do
85
+ # be careful to explicitly close files so that the
86
+ # directory can be removed and we don't have to wait for
87
+ # the GC to run.
88
+ expected_trace_data = open('spec/data/expected_trace.out').read
89
+ trace_file = open("#{@test_directory}/test_trace.out", 'w')
90
+ @conn.trace(trace_file)
91
+ trace_file.close
92
+ res = @conn.exec("SELECT 1 AS one")
93
+ @conn.untrace
94
+ res = @conn.exec("SELECT 2 AS two")
95
+ trace_file = open("#{@test_directory}/test_trace.out")
96
+ trace_data = trace_file.read
97
+ trace_file.close
98
+ trace_data.should == expected_trace_data
99
+ end
100
+
101
+ it "should cancel a query" do
102
+ error = false
103
+ @conn.send_query("SELECT pg_sleep(1000)")
104
+ @conn.cancel
105
+ begin
106
+ tmpres = @conn.get_result
107
+ rescue PGError => e
108
+ error = true
109
+ end
110
+ error.should == true
111
+ end
112
+
113
+ after( :all ) do
114
+ puts ""
115
+ @conn.finish
116
+ cmds = []
117
+ cmds << "pg_ctl -D '#{@test_pgdata}' stop"
118
+ cmds << "rm -rf '#{@test_directory}'"
119
+ cmds.each do |cmd|
120
+ if not system(cmd) then
121
+ raise "Error executing cmd: #{cmd}: #{$?}"
122
+ end
123
+ end
124
+ puts "====== COMPLETED TESTING PGconn ======"
125
+ puts ""
126
+ end
127
+ end