Little parser question - Mailing list pgsql-hackers

From jwieck@debis.com (Jan Wieck)
Subject Little parser question
Date
Msg-id m0zNgbI-000EBPC@orion.SAPserv.Hamburg.dsh.de
Whole thread Raw
Responses Re: [HACKERS] Little parser question  (Bruce Momjian <maillist@candle.pha.pa.us>)
List pgsql-hackers
Hi,

    while  fixing  the  subselect  parseback  in the new ruleutil
    functions and checking if the output is now what's needed for
    dumping  rules/views  I  came  across  a little detail in the
    parser I'm confused about.

    Having a table

    CREATE TABLE t1 (a char(20));

    the two statements

    INSERT INTO t1 VALUES ('x');

    INSERT INTO t1 VALUES ('x'::bpchar);

    produce mainly the same parsetree (where the const value  'x'
    of  type 1042 is embedded into a call to bpchar(bpchar, int4)
    for the padding).

    But in the first case argument 1 is constbyval  TRUE  and  in
    the  second  one  FALSE (where I feel the second one is right
    for a bpchar const). Seems that it doesn't matter later.

    The ruleutil functions output the typecasting  any  time  and
    this  little  detail makes it harder for me to check if their
    output really recreates all the rules as the original  CREATE
    statements did.

    The  output  from  the  ruleutil functions can differ in many
    cases from the original CREATE commands  (for  'AS  funcname'
    where no one was given and in the subselects area where 'attr
    in (val, val, ...)'  will  be  explicit  OR  list,  'attr  IN
    (SELECT  ...' will be output as 'attr = ANY (SELECT ...'  and
    so on).  But the resulting rules will be the same AFAIK.

    For checking the output to be O.K. I took all the  pg_rewrite
    content from a regression database (plus some more views with
    subselects etc.) into a temp  file,  dropped  all  rules  and
    recreated  them from what pg_rules printed. Then I took again
    all the pg_rewrite content and expected the same (and got  it
    except for the constbyval diffs).

    I'll send in the fixes for ruleutils soon.

    If  someone likes to add dumping rules/views to pg_dump, some
    little background details:

        Views could be nested (one view selects another view). So
        restoring by CREATE VIEW depends on the correct order.

        But  a  view  could  also be recreated by a CREATE TABLE,
        CREATE RULE, UPDATE pg_rewrite sequence.  This  time,  if
        all  the  CREATE  TABLE statements are made first and the
        CREATE RULE ones later, they don't depend on  each  other
        any more.

        The  view  pg_rules  will  (as  mentioned  by  Keith) not
        include view rules any  longer.  So  pg_dump  should  use
        function  pg_get_ruledef()  directly on pg_rewrite to get
        all the rules definitions.

        To reconstruct anything correct it must  be  executed  in
        the following order:

        Step 1: Create all tables and views as regular tables.

        Step  2:  Insert  all  data  (where  tables  that have an
        INSTEAD rule on SELECT named _RET<tablename>  receive  no
        data at all).

        Step  3: Create all rules (except the ones named _RETpg_*
        from system views) and rename the  remaining  _RET*  ones
        from _ret* to _RET* (CREATE RULE converts the rulename to
        lower  case  -  that's  why  the  UPDATE  pg_rewrite   is
        required).

    Inserting  the  data before recreating the rules is necessary
    because rules could fire more actions  on  insert,  and  that
    isn't wanted at reload time.


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#======================================== jwieck@debis.com (Jan Wieck) #

pgsql-hackers by date:

Previous
From: Massimo Dal Zotto
Date:
Subject: Re: [HACKERS] It sorta works, but I'm confused about locking
Next
From: Massimo Dal Zotto
Date:
Subject: Re: [HACKERS] Proper cleanup at backend exit