Unix Technical Forum

Re: Final version of IDENTITY/GENERATED patch

This is a discussion on Re: Final version of IDENTITY/GENERATED patch within the Pgsql Patches forums, part of the PostgreSQL category; --> Tom Lane írta: > Zoltan Boszormenyi <zb@cybertec.at> writes: > >> Andrew Dunstan írta: >> >>> Zoltan Boszormenyi wrote: >>> ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > Pgsql Patches

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #31 (permalink)  
Old 04-18-2008, 10:58 AM
Zoltan Boszormenyi
 
Posts: n/a
Default Re: [HACKERS] parser dilemma

Tom Lane írta:
> Zoltan Boszormenyi <zb@cybertec.at> writes:
>
>> Andrew Dunstan írta:
>>
>>> Zoltan Boszormenyi wrote:
>>>
>>>> On the other hand, marking GENERATED as %right
>>>> solves this issue. I hope it's an acceptable solution.
>>>>
>>> If anything I should have thought it would be marked %nonassoc.
>>>

>
>
>> That works, too.
>>

>
> [ a bit alarmed... ] This is only going to be an acceptable solution
> if you can explain *exactly why* it works. The general story with
> associativity/precedence declarations is that you are making bison
> resolve ambiguous situations in particular ways. If you don't have a
> 100% clear understanding of what the ambiguity is and why this is the
> right way to resolve it, you are probably creating a bigger problem.
>
> regards, tom lane
>


As far as I remember from my math classes, associativity is
the rules about the way brackets are allowed to be used.
Say, multiplication is two-way associative, i.e.:

a * b * c == (a * b) * c == a * (b * c)

If it was only left associative, the line below would be true:

a * b * c == (a * b) * c != a * (b * c)

Similarly, if it was only right-associative, this would be true:

a * b * c == a * (b * c) != (a * b) * c

Precedence is about the implicit bracketing above
two operators, i.e.

a * b + c * d == (a * b) + (c * d)

(Sorry for the poor explanation, my math classes weren't in English.)

So, before marking, bison was able to do this association:

colname coltype ( DEFAULT 5! GENERATED ) ALWAYS ...

after marking GENERATED as %right, it can only do this:

colname coltype DEFAULT 5! ( GENERATED ALWAYS ... )

With marking GENERATED as %nonassoc, it cannot do either,
leaving the only option for associating DEFAULT as:

colname coltype (DEFAULT 5!) (GENERATED) ALWAYS ...

So, do any of these cause any problems?

--
----------------------------------
Zoltán Böszörményi
Cybertec Geschwinde & Schönig GmbH
http://www.postgresql.at/


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #32 (permalink)  
Old 04-18-2008, 10:58 AM
Tom Lane
 
Posts: n/a
Default Re: [HACKERS] parser dilemma

Zoltan Boszormenyi <zb@cybertec.at> writes:
> Tom Lane írta:
>> [ a bit alarmed... ] This is only going to be an acceptable solution
>> if you can explain *exactly why* it works. The general story with
>> associativity/precedence declarations is that you are making bison
>> resolve ambiguous situations in particular ways.


> So, before marking, bison was able to do this association:
>
> colname coltype ( DEFAULT 5! GENERATED ) ALWAYS ...
>
> after marking GENERATED as %right, it can only do this:
>
> colname coltype DEFAULT 5! ( GENERATED ALWAYS ... )
>
> With marking GENERATED as %nonassoc, it cannot do either,
> leaving the only option for associating DEFAULT as:
>
> colname coltype (DEFAULT 5!) (GENERATED) ALWAYS ...


Well, as I was saying, safe use of these options requires knowing
exactly what you're doing, and evidently you don't :-(. The above
explanation has got about nothing to do with what Bison really does
with associativity/precedence; you need to read the precedence pages
in the Bison manual.

The reason your patch makes it appear to work is not associativity;
it is that you assigned GENERATED a precedence lower than POSTFIXOP.
This means that when Bison is considering whether to reduce a
postfix-operator rule, and GENERATED is the next token, it'll choose
to reduce. The problem is that that isn't necessarily the right
action; in particular, it makes GENERATED act differently from other
identifiers. Remember that the whole point here is to keep GENERATED
a non-reserved word. Supposing that someone had a column named
GENERATED, your patch would make these queries parse differently:

select x ! generated from ...

select x ! y from ...

So I think attaching a precedence to the GENERATED keyword is dangerous.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #33 (permalink)  
Old 04-18-2008, 10:58 AM
Andrew Dunstan
 
Posts: n/a
Default Re: [HACKERS] parser dilemma



Tom Lane wrote:
>
> So I think attaching a precedence to the GENERATED keyword is dangerous.
>
>


Especially when we have a good workaround which would just require use
of () around certain postfix-operator expressions.

cheers

andrew

---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #34 (permalink)  
Old 04-18-2008, 10:58 AM
Tom Lane
 
Posts: n/a
Default Re: [HACKERS] parser dilemma

Andrew Dunstan <andrew@dunslane.net> writes:
> Tom Lane wrote:
>> So I think attaching a precedence to the GENERATED keyword is dangerous.


> Especially when we have a good workaround which would just require use
> of () around certain postfix-operator expressions.


Yeah, I'm leaning to the idea that removing postfix operators from
b_expr is the least bad solution.

One thing that would have to be looked at is the rules in ruleutils.c
for suppressing "unnecessary" parentheses when reverse-listing
parsetrees. It might be safest to just never suppress them around a
postfix operator.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #35 (permalink)  
Old 04-18-2008, 10:59 AM
Zoltan Boszormenyi
 
Posts: n/a
Default Re: [HACKERS] parser dilemma

Tom Lane írta:
> Andrew Dunstan <andrew@dunslane.net> writes:
>
>> Tom Lane wrote:
>>
>>> So I think attaching a precedence to the GENERATED keyword is dangerous.
>>>

>
>
>> Especially when we have a good workaround which would just require use
>> of () around certain postfix-operator expressions.
>>

>
> Yeah, I'm leaning to the idea that removing postfix operators from
> b_expr is the least bad solution.
>
> One thing that would have to be looked at is the rules in ruleutils.c
> for suppressing "unnecessary" parentheses when reverse-listing
> parsetrees. It might be safest to just never suppress them around a
> postfix operator.
>
> regards, tom lane
>


You mean something like this?

-----------------------------------------------------
***************
*** 4138,4157 ****
Oid opno = expr->opno;
List *args = expr->args;

- if (!PRETTY_PAREN(context))
- appendStringInfoChar(buf, '(');
if (list_length(args) == 2)
{
/* binary operator */
Node *arg1 = (Node *) linitial(args);
Node *arg2 = (Node *) lsecond(args);

get_rule_expr_paren(arg1, context, true, (Node *) expr);
appendStringInfo(buf, " %s ",

generate_operator_name(opno,

exprType(arg1),

exprType(arg2)));
get_rule_expr_paren(arg2, context, true, (Node *) expr);
}
else
{
--- 4095,4118 ----
Oid opno = expr->opno;
List *args = expr->args;

if (list_length(args) == 2)
{
/* binary operator */
Node *arg1 = (Node *) linitial(args);
Node *arg2 = (Node *) lsecond(args);

+ if (!PRETTY_PAREN(context))
+ appendStringInfoChar(buf, '(');
+
get_rule_expr_paren(arg1, context, true, (Node *) expr);
appendStringInfo(buf, " %s ",

generate_operator_name(opno,

exprType(arg1),

exprType(arg2)));
get_rule_expr_paren(arg2, context, true, (Node *) expr);
+
+ if (!PRETTY_PAREN(context))
+ appendStringInfoChar(buf, ')');
}
else
{
***************
*** 4169,4194 ****
switch (optup->oprkind)
{
case 'l':
appendStringInfo(buf, "%s ",

generate_operator_name(opno,

InvalidOid,

exprType(arg)));
get_rule_expr_paren(arg, context, true,
(Node *) expr);
break;
case 'r':
get_rule_expr_paren(arg, context, true,
(Node *) expr);
appendStringInfo(buf, " %s",

generate_operator_name(opno,

exprType(arg),

InvalidOid));
break;
default:
elog(ERROR, "bogus oprkind: %d",
optup->oprkind);
}
ReleaseSysCache(tp);
}
- if (!PRETTY_PAREN(context))
- appendStringInfoChar(buf, ')');
}

/*
--- 4130,4159 ----
switch (optup->oprkind)
{
case 'l':
+ if (!PRETTY_PAREN(context))
+ appendStringInfoChar(buf, '(');
appendStringInfo(buf, "%s ",

generate_operator_name(opno,

InvalidOid,

exprType(arg)));
get_rule_expr_paren(arg, context, true,
(Node *) expr);
+ if (!PRETTY_PAREN(context))
+ appendStringInfoChar(buf, ')');
break;
case 'r':
+ appendStringInfoChar(buf, '(');
get_rule_expr_paren(arg, context, true,
(Node *) expr);
appendStringInfo(buf, " %s",

generate_operator_name(opno,

exprType(arg),

InvalidOid));
+ appendStringInfoChar(buf, ')');
break;
default:
elog(ERROR, "bogus oprkind: %d",
optup->oprkind);
}
ReleaseSysCache(tp);
}
}

/*
-----------------------------------------------------

It seems to work:

-----------------------------------------------------
$ psql
Welcome to psql 8.3devel, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

zozo=# create table t1 (i integer default 5! generated always as
identity primary key, t text not null unique);
ERROR: syntax error at or near "always"
LINE 1: create table t1 (i integer default 5! generated always as id...
^
zozo=# create table t1 (i integer default (5!) generated always as
identity primary key, t text not null unique);
NOTICE: CREATE TABLE will create implicit sequence "t1_i_seq" for
serial column "t1.i"
ERROR: multiple default values specified for column "i" of table "t1"
zozo=# create table t1 (i integer default (5!) primary key, t text not
null unique);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey"
for table "t1"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "t1_t_key" for
table "t1"
CREATE TABLE
zozo=# \d t1
Table "public.t1"
Column | Type | Modifiers
--------+---------+----------------------------------
i | integer | not null default ((5)::bigint !)
t | text | not null
Indexes:
"t1_pkey" PRIMARY KEY, btree (i)
"t1_t_key" UNIQUE, btree (t)

zozo=# \q
$ pg_dump
....
--
-- Name: t1; Type: TABLE; Schema: public; Owner: zozo; Tablespace:
--

CREATE TABLE t1 (
i integer DEFAULT ((5)::bigint !) NOT NULL,
t text NOT NULL
);

....

--
-- PostgreSQL database dump complete
--
-----------------------------------------------------

So, if I send the patch again (POSTFIXOP deleted from b_expr)
with the above added, will it get accepted?

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Geschwinde & Schönig GmbH
http://www.postgresql.at/


---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #36 (permalink)  
Old 04-18-2008, 10:59 AM
Zoltan Boszormenyi
 
Posts: n/a
Default New version of GENERATED/IDENTITY, was Re: parser dilemma

Hi,

here's the patch with the modifications suggested by Tom Lane.
The postfix rule was deleted from b_expr and the reverse parsing
in ruleutils.c::get_oper_expr() always puts parentheses around
postfix operators.

Other changes:
- OVERRIDING SYSTEM VALUE in COPY can appear
at any place in the option list.
- pg_dump was modified accordingly
- \copy built-in in psql now also accepts OVERRIDING SYSTEM VALUE
- documentation and testcase updates

Please, review.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Geschwinde & Schönig GmbH
http://www.postgresql.at/


---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 05:23 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com