Changeset 17 for trunk/epic

Show
Ignore:
Timestamp:
08/26/08 22:52:40 (4 years ago)
Author:
fumanchu
Message:

Some little bugfixes, plus a new typename function.

Location:
trunk/epic
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/epic/epic.sql

    r15 r17  
    246246CREATE OR REPLACE FUNCTION global(call text) RETURNS record AS $$ 
    247247-- Stores the given call's output in a TEMP table, and returns it as a record. 
     248-- If the call produces several rows, only the first record is returned. 
    248249--  
    249250-- 'call' can be any SELECT, table, view, or procedure that returns records. 
     
    259260BEGIN 
    260261  tablename := '_global_' || nextval('_global_ids'); 
    261   EXECUTE 'CREATE TEMP TABLE ' || tablename || ' AS ' || statement(call); 
    262   EXECUTE 'SELECT ''' || tablename || '''::text AS tablename, * FROM ' || tablename INTO result; 
     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; 
    263268  RETURN result; 
    264269END; 
     
    278283    RETURN NEXT rec; 
    279284  END LOOP; 
     285END; 
     286$$ LANGUAGE plpgsql; 
     287 
     288 
     289CREATE OR REPLACE FUNCTION typename(elem anyelement) RETURNS text AS $$ 
     290-- Return the typename of the given element. 
     291DECLARE 
     292  name    text; 
     293BEGIN 
     294  CREATE TEMP TABLE _elem_type AS SELECT elem; 
     295  SELECT INTO name pgt.typname 
     296    FROM pg_attribute pga LEFT JOIN pg_type pgt ON pga.atttypid = pgt.oid 
     297    WHERE pga.attrelid = (SELECT oid FROM pg_class WHERE relname = '_elem_type') 
     298    AND pga.attnum = 1; 
     299  DROP TABLE _elem_type; 
     300  RETURN name; 
    280301END; 
    281302$$ LANGUAGE plpgsql; 
     
    434455  retval    text; 
    435456BEGIN 
    436   EXECUTE statement(call) INTO retval; 
     457  EXECUTE test.statement(call) INTO retval; 
    437458  IF retval != '' THEN 
    438459    RAISE EXCEPTION 'Call: ''%'' did not return void. Got ''%'' instead.', call, retval; 
     
    566587BEGIN 
    567588  BEGIN 
    568     EXECUTE statement(call); 
     589    EXECUTE test.statement(call); 
    569590  EXCEPTION 
    570591    WHEN OTHERS THEN 
     
    611632  e       text; 
    612633BEGIN 
    613   s := statement(source); 
    614   e := statement(expected); 
     634  s := test.statement(source); 
     635  e := test.statement(expected); 
    615636   
    616637  FOR rec in EXECUTE s || ' EXCEPT ' || e 
     
    649670  -- Dump the call output into a temp table 
    650671  IF colname IS NULL THEN 
    651     EXECUTE 'CREATE TEMPORARY TABLE _test_assert_values_base AS ' || statement(call); 
     672    EXECUTE 'CREATE TEMPORARY TABLE _test_assert_column_base AS ' || test.statement(call); 
    652673    SELECT INTO firstname a.attname 
    653674      FROM pg_class c LEFT JOIN pg_attribute a ON c.oid = a.attrelid 
    654       WHERE c.relname = '_test_assert_values_base' 
     675      WHERE c.relname = '_test_assert_column_base' 
    655676      -- "The number of the column. Ordinary columns are numbered from 1 up. 
    656677      -- System columns, such as oid, have (arbitrary) negative numbers" 
    657678      AND a.attnum >= 1 
    658679      ORDER BY a.attnum; 
    659     EXECUTE 'ALTER TABLE _test_assert_values_base RENAME ' || firstname || ' TO _assert_values_result;'; 
     680    EXECUTE 'ALTER TABLE _test_assert_column_base RENAME ' || firstname || ' TO _assert_column_result;'; 
    660681  ELSE 
    661     EXECUTE 'CREATE TEMPORARY TABLE _test_assert_values_base AS ' || 
    662       'SELECT ' || colname || ' AS _assert_values_result FROM ' || call || ';'; 
     682    EXECUTE 'CREATE TEMPORARY TABLE _test_assert_column_base AS ' || 
     683      'SELECT ' || colname || ' AS _assert_column_result FROM ' || call || ';'; 
    663684  END IF; 
    664685   
     
    666687  -- Use EXECUTE for all statements involving this table so its query plan 
    667688  -- doesn't get cached and re-used (or subsequent calls will fail). 
    668   EXECUTE 'CREATE TEMPORARY TABLE _test_assert_values_expected (LIKE _test_assert_values_base);'; 
     689  EXECUTE 'CREATE TEMPORARY TABLE _test_assert_column_expected (LIKE _test_assert_column_base);'; 
    669690  FOR i IN array_lower(expected, 1)..array_upper(expected, 1) 
    670691  LOOP 
    671692    IF expected[i] IS NULL THEN 
    672       EXECUTE 'INSERT INTO _test_assert_values_expected (_assert_values_result) VALUES (NULL);'; 
     693      EXECUTE 'INSERT INTO _test_assert_column_expected (_assert_column_result) VALUES (NULL);'; 
     694    ELSEIF typename(expected[i]) IN ('text', 'varchar', 'char', 'bytea', 'date', 'timestamp', 'timestamptz', 'time', 'timetz') THEN 
     695      EXECUTE 'INSERT INTO _test_assert_column_expected (_assert_column_result) VALUES (' 
     696              || quote_literal(expected[i]) || ');'; 
    673697    ELSE 
    674       EXECUTE 'INSERT INTO _test_assert_values_expected (_assert_values_result) VALUES (' 
    675               || quote_literal(expected[i]) || ');'; 
     698      EXECUTE 'INSERT INTO _test_assert_column_expected (_assert_column_result) VALUES (' 
     699              || expected[i] || ');'; 
    676700    END IF; 
    677701  END LOOP; 
     
    680704  <<TRY>> 
    681705  BEGIN 
    682     FOR record IN EXECUTE '(SELECT * FROM _test_assert_values_base EXCEPT ALL 
    683                             SELECT * FROM _test_assert_values_expected)' 
     706    FOR record IN EXECUTE '(SELECT * FROM _test_assert_column_base EXCEPT ALL 
     707                            SELECT * FROM _test_assert_column_expected)' 
    684708    LOOP 
    685       RAISE EXCEPTION 'result: % not in array: %', record._assert_values_result, expected; 
     709      RAISE EXCEPTION 'result: % not in array: %', record._assert_column_result, expected; 
    686710    END LOOP; 
    687711     
    688     FOR record IN EXECUTE '(SELECT * FROM _test_assert_values_expected EXCEPT ALL 
    689                             SELECT * FROM _test_assert_values_base)' 
     712    FOR record IN EXECUTE '(SELECT * FROM _test_assert_column_expected EXCEPT ALL 
     713                            SELECT * FROM _test_assert_column_base)' 
    690714    LOOP 
    691       RAISE EXCEPTION 'element: % not in call: %', record._assert_values_result, call; 
     715      RAISE EXCEPTION 'element: % not in call: %', record._assert_column_result, call; 
    692716    END LOOP; 
    693717  EXCEPTION WHEN OTHERS THEN 
    694     DROP TABLE _test_assert_values_base; 
    695     EXECUTE 'DROP TABLE _test_assert_values_expected'; 
     718    DROP TABLE _test_assert_column_base; 
     719    EXECUTE 'DROP TABLE _test_assert_column_expected'; 
    696720    RAISE EXCEPTION '%', SQLERRM; 
    697721  END TRY; 
    698722   
    699   DROP TABLE _test_assert_values_base; 
    700   EXECUTE 'DROP TABLE _test_assert_values_expected'; 
     723  DROP TABLE _test_assert_column_base; 
     724  EXECUTE 'DROP TABLE _test_assert_column_expected'; 
    701725END; 
    702726$$ LANGUAGE plpgsql; 
  • trunk/epic/test/test_asserts.sql

    r14 r17  
    358358    ARRAY[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 
    359359    'generate_series'); 
     360  -- text fields 
     361  PERFORM test.assert_column( 
     362    'pg_namespace WHERE nspname IN (''public'', ''test'')', 
     363    ARRAY['public', 'test'], 
     364    'nspname'); 
     365  -- timestamp fields. This also tests omitted colname 
     366  PERFORM test.assert_column( 
     367    'SELECT ''2007-04-13 09:28:54.132132''::timestamptz', 
     368    ARRAY['2007-04-13 09:28:54.132132'::timestamptz]); 
    360369   
    361370  -- ...and an assertion that should fail