Changeset 22
- Timestamp:
- 09/03/08 08:55:33 (3 years ago)
- Location:
- trunk/epic
- Files:
-
- 2 modified
-
epic.sql (modified) (3 diffs)
-
test/test_globals.sql (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/epic/epic.sql
r21 r22 244 244 245 245 246 -- Note this is in the public schema!! 247 CREATE OR REPLACE FUNCTION _global_record(tablename text, creator text) RETURNS record AS $$ 248 DECLARE 249 result record; 250 record_stmt text; 251 BEGIN 252 EXECUTE 'SELECT NULL::text AS __name__, NULL::text AS __create__, ' 253 || 'NULL::text AS __record__, NULL::text AS __iter__, ' 254 || 'NULL::text AS __attributes__, 0::int AS __len__, ' 255 || '* FROM ' || tablename || ' LIMIT 1' INTO result; 256 257 -- We add these values outside the EXECUTE in case the TEMP table has no rows. 258 result.__name__ := tablename; 259 result.__create__ := creator; 260 result.__record__ := 'SELECT * FROM _global_record(''' || tablename || ''', ''' || creator || ''')'; 261 result.__iter__ := 'SELECT * FROM ' || tablename; 262 result.__attributes__ := 'SELECT attname FROM test.attributes(''' || tablename || ''')'; 263 EXECUTE 'SELECT COUNT(*) FROM ' || tablename INTO result.__len__; 264 265 RETURN result; 266 END; 267 $$ LANGUAGE plpgsql; 268 269 270 -- Note this is in the public schema!! 246 271 CREATE OR REPLACE FUNCTION global(call text) RETURNS record AS $$ 247 272 -- Stores the given call's output in a TEMP table, and returns it as a record. … … 251 276 -- 252 277 -- The returned record includes the following additional attributes: 253 -- * tablename (text): The complete name of the TEMP table. This allows you 254 -- to pass my_record_var.tablename to functions that take a 'call text' 255 -- argument, such as assert_column, assert_values, and assert_empty 256 -- (since no procedural languages support passing records as args). 278 -- * __name__ (text): The complete name of the TEMP table. This allows you 279 -- to pass g.__name__ to functions that take a 'call text' argument, 280 -- such as assert_column, assert_values, and assert_empty (since no 281 -- procedural languages support passing records as args). 282 -- * __create__ (text): The SQL statement used to construct the table. 283 -- * __record__ (text): The SQL statement used to construct the returned record. 284 -- Use this to copy the returned record (perhaps in another function). 285 -- Example: EXECUTE g.__record__ INTO g2; 286 -- * __iter__ (text): An SQL string to SELECT * FROM the TEMP table. 287 -- Example: FOR record IN EXECUTE g.__iter__ 288 -- * __attributes__ (text): The SQL string for TEMP table column names. 289 -- Example: FOR colname IN EXECUTE g.__attributes__ 290 -- * __len__ (int): The number of rows in the TEMP table. This value 291 -- is NOT updated if you change the table after its creation. 257 292 DECLARE 258 293 tablename text; 294 creator text; 259 295 result record; 260 296 BEGIN 261 297 tablename := '_global_' || nextval('_global_ids'); 262 EXECUTE 'CREATE TEMP TABLE ' || tablename || ' AS ' || test.statement(call); 263 EXECUTE 'SELECT ''' || tablename || '''::text AS tablename, * FROM ' || tablename || ' LIMIT 1' INTO result; 264 IF result.tablename IS NULL THEN 265 -- Our temp table has no rows, so our tablename wasn't selected either. 266 result.tablename := tablename; 267 END IF; 298 creator := test.statement(call); 299 EXECUTE 'CREATE TEMP TABLE ' || tablename || ' AS ' || creator; 300 result := _global_record(tablename, creator); 268 301 RETURN result; 269 302 END; … … 271 304 272 305 273 CREATE OR REPLACE FUNCTION attributes(tablename text) RETURNS SETOF pg_attribute AS $$306 CREATE OR REPLACE FUNCTION test.attributes(tablename text) RETURNS SETOF pg_attribute AS $$ 274 307 DECLARE 275 308 rec record; -
trunk/epic/test/test_globals.sql
r16 r22 12 12 PERFORM test.assert_equal(rec.nspname, 'test'); 13 13 14 -- The returned record MUST possess a . tablenameattribute.15 PERFORM test.assert(rec. tablename LIKE E'\_global\_%', rec.tablename|| ' not like _global');14 -- The returned record MUST possess a .__name__ attribute. 15 PERFORM test.assert(rec.__name__ LIKE E'\_global\_%', rec.__name__ || ' not like _global'); 16 16 17 -- The tablenameMUST reference a temporary table with the same fields.18 EXECUTE 'SELECT * FROM ' || rec. tablenameINTO trec;17 -- The .__name__ MUST reference a temporary table with the same fields. 18 EXECUTE 'SELECT * FROM ' || rec.__name__ INTO trec; 19 19 PERFORM test.assert_equal(trec.nspname, 'test'); 20 20 PERFORM test.assert_equal(trec.nspowner, rec.nspowner); 21 21 PERFORM test.assert_equal(trec.nspacl, rec.nspacl); 22 22 23 RAISE EXCEPTION '%', rec.tablename; 23 -- The returned record MUST possess a .__create__ attribute. 24 PERFORM test.assert_equal(rec.__create__, 'SELECT * FROM pg_namespace WHERE nspname = ''test'''); 25 26 -- The returned record MUST possess a .__record__ attribute. 27 PERFORM test.assert_equal(rec.__record__, 28 'SELECT * FROM _global_record(''' || rec.__name__ || ''', ''' || rec.__create__ || ''')'); 29 30 -- The returned record MUST possess an .__iter__ attribute. 31 PERFORM test.assert_equal(rec.__iter__, 'SELECT * FROM ' || rec.__name__); 32 PERFORM test.assert_not_empty(rec.__iter__); 33 34 -- The returned record MUST possess an .__attributes__ attribute. 35 PERFORM test.assert_equal(rec.__attributes__, 'SELECT attname FROM test.attributes(''' || rec.__name__ || ''')'); 36 PERFORM test.assert_column(rec.__attributes__, ARRAY['nspname', 'nspowner', 'nspacl']); 37 38 -- The returned record MUST possess a .__len__ attribute. 39 PERFORM test.assert_equal(rec.__len__, 1); 40 41 -- Raise an exception to test deletion of the TEMP table ON COMMIT 42 RAISE EXCEPTION '%', rec.__name__; 24 43 END; 25 44 $$ LANGUAGE plpgsql;
