Thread: Little parser question

Little parser question

From
jwieck@debis.com (Jan Wieck)
Date:
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) #

Re: [HACKERS] Little parser question

From
"Thomas G. Lockhart"
Date:
> 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.

Without actually looking at the code, I'm pretty sure that the
unspecified constant string in the first insert above is getting
interpreted as a string of type UNKNOWN. Apparently it actually tests
for the length of the string and tries to do a "pass by value" if it can
fit.

I don't see this as being a big win, and if you would find it easier we
could try to track it down and make UNKNOWN a pass by reference always.

btw, the call to bpchar(bpchar,int4) is part of my new type coersion
code; this is the first release that will actually check and truncate
strings as they are being stored into a table. In previous releases
longer strings which were the result of, for example, a concatenation
were not length-checked on storage into the table.

Anyway, let me know what you'd like...

                        - Tom

Re: [HACKERS] Little parser question

From
Bruce Momjian
Date:
> 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.

I have just committed a fix for this.  The parse_coerce code was not
setting the constbyval dependent on the type.  There were a few other
places where this was not set properly, and those are fixed now.

--
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026