BETWEEN SYMMETRIC/ASYMMETRIC

Started by Christopher Kings-Lynnealmost 24 years ago20 messages
#1Christopher Kings-Lynne
chriskl@familyhealth.com.au
1 attachment(s)

Hi all,

I've attached a patch for doing BETWEEN SYM/ASYM, however it just doesn't
work!!!

test=# select 2 between 1 and 3;
?column?
----------
t
(1 row)

test=# select 2 between 3 and 1;
?column?
----------
f
(1 row)

test=# select 2 between symmetric 3 and 1;
ERROR: parser: parse error at or near "3"
test=# select 2 between asymmetric 3 and 1;
ERROR: parser: parse error at or near "3"
test=# select 2 not between 3 and 1;
?column?
----------
t
(1 row)

test=# select 2 not between symmetric 3 and 1;
ERROR: parser: parse error at or near "3"

Can anyone see what's wrong?

Chris

Attachments:

between.txttext/plain; name=between.txtDownload
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.301
diff -c -r2.301 gram.y
*** src/backend/parser/gram.y	2002/04/09 20:35:51	2.301
--- src/backend/parser/gram.y	2002/04/10 02:58:38
***************
*** 346,352 ****
  		IMMEDIATE, INITIALLY, INOUT,
  		OFF, OUT,
  		PATH_P, PENDANT,
! 		REPLACE, RESTRICT,
          TRIGGER,
  		WITHOUT
  
--- 346,352 ----
  		IMMEDIATE, INITIALLY, INOUT,
  		OFF, OUT,
  		PATH_P, PENDANT,
! 		REPLACE, RESTRICT, SYMMETRIC, ASYMMETRIC,
          TRIGGER,
  		WITHOUT
  
***************
*** 4916,4923 ****
  		| a_expr BETWEEN b_expr AND b_expr			%prec BETWEEN
  				{
  					$$ = makeA_Expr(AND, NULL,
! 						makeA_Expr(OP, ">=", $1, $3),
! 						makeA_Expr(OP, "<=", $1, $5));
  				}
  		| a_expr NOT BETWEEN b_expr AND b_expr		%prec BETWEEN
  				{
--- 4916,4942 ----
  		| a_expr BETWEEN b_expr AND b_expr			%prec BETWEEN
  				{
  					$$ = makeA_Expr(AND, NULL,
! 							makeA_Expr(OP, ">=", $1, $3),
! 							makeA_Expr(OP, "<=", $1, $5));
! 
! 				}
! 		| a_expr BETWEEN ASYMMETRIC b_expr AND b_expr			%prec BETWEEN
! 				{
! 					$$ = makeA_Expr(AND, NULL,
! 							makeA_Expr(OP, ">=", $1, $4),
! 							makeA_Expr(OP, "<=", $1, $6));
! 
! 				}
! 		| a_expr BETWEEN SYMMETRIC b_expr AND b_expr			%prec BETWEEN
! 				{
! 					$$ = makeA_Expr(OR, NULL,
! 						makeA_Expr(AND, NULL,
! 							makeA_Expr(OP, ">=", $1, $4),
! 							makeA_Expr(OP, "<=", $1, $6)),
! 						makeA_Expr(AND, NULL,
! 							makeA_Expr(OP, ">=", $1, $6),
! 							makeA_Expr(OP, "<=", $1, $4))
! 					);
  				}
  		| a_expr NOT BETWEEN b_expr AND b_expr		%prec BETWEEN
  				{
***************
*** 4925,4930 ****
--- 4944,4966 ----
  						makeA_Expr(OP, "<", $1, $4),
  						makeA_Expr(OP, ">", $1, $6));
  				}
+ 		| a_expr NOT BETWEEN ASYMMETRIC b_expr AND b_expr		%prec BETWEEN
+ 				{
+ 					$$ = makeA_Expr(OR, NULL,
+ 						makeA_Expr(OP, "<", $1, $5),
+ 						makeA_Expr(OP, ">", $1, $7));
+ 				}
+ 		| a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr		%prec BETWEEN
+ 				{
+ 					$$ = makeA_Expr(AND, NULL,
+ 						makeA_Expr(OR, NULL,
+ 							makeA_Expr(OP, "<", $1, $5),
+ 							makeA_Expr(OP, ">", $1, $7)),
+ 						makeA_Expr(OR, NULL,
+ 							makeA_Expr(OP, "<", $1, $7),
+ 							makeA_Expr(OP, ">", $1, $5))
+ 					);
+ 				}
  		| a_expr IN in_expr
  				{
  					/* in_expr returns a SubLink or a list of a_exprs */
***************
*** 6093,6099 ****
   * looks too much like a function call for an LR(1) parser.
   */
  col_name_keyword:
! 		  BIT							{ $$ = "bit"; }
  		| CHAR							{ $$ = "char"; }
  		| CHARACTER						{ $$ = "character"; }
  		| COALESCE						{ $$ = "coalesce"; }
--- 6129,6135 ----
   * looks too much like a function call for an LR(1) parser.
   */
  col_name_keyword:
! 		 BIT							{ $$ = "bit"; }
  		| CHAR							{ $$ = "char"; }
  		| CHARACTER						{ $$ = "character"; }
  		| COALESCE						{ $$ = "coalesce"; }
***************
*** 6127,6133 ****
   *  - thomas 2000-11-28
   */
  func_name_keyword:
! 		  AUTHORIZATION					{ $$ = "authorization"; }
  		| BETWEEN						{ $$ = "between"; }
  		| BINARY						{ $$ = "binary"; }
  		| CROSS							{ $$ = "cross"; }
--- 6163,6169 ----
   *  - thomas 2000-11-28
   */
  func_name_keyword:
! 		 AUTHORIZATION					{ $$ = "authorization"; }
  		| BETWEEN						{ $$ = "between"; }
  		| BINARY						{ $$ = "binary"; }
  		| CROSS							{ $$ = "cross"; }
***************
*** 6163,6168 ****
--- 6199,6205 ----
  		| AND							{ $$ = "and"; }
  		| ANY							{ $$ = "any"; }
  		| AS							{ $$ = "as"; }
+ 		| ASYMMETRIC						{ $$ = "asymmetric"; }
  		| ASC							{ $$ = "asc"; }
  		| BOTH							{ $$ = "both"; }
  		| CASE							{ $$ = "case"; }
***************
*** 6211,6216 ****
--- 6248,6254 ----
  		| SELECT						{ $$ = "select"; }
  		| SESSION_USER					{ $$ = "session_user"; }
  		| SOME							{ $$ = "some"; }
+ 		| SYMMETRIC						{ $$ = "symmetric"; }
  		| TABLE							{ $$ = "table"; }
  		| THEN							{ $$ = "then"; }
  		| TO							{ $$ = "to"; }
#2Gavin Sherry
swm@linuxworld.com.au
In reply to: Christopher Kings-Lynne (#1)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

On Wed, 10 Apr 2002, Christopher Kings-Lynne wrote:

Hi all,

I've attached a patch for doing BETWEEN SYM/ASYM, however it just doesn't
work!!!

test=# select 2 between 1 and 3;
?column?
----------
t
(1 row)

test=# select 2 between 3 and 1;
?column?
----------
f
(1 row)

test=# select 2 between symmetric 3 and 1;
ERROR: parser: parse error at or near "3"
test=# select 2 between asymmetric 3 and 1;
ERROR: parser: parse error at or near "3"

Chris,

You seem to have forgotten to update keywords.c.

Gavin

#3Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Gavin Sherry (#2)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

Chris,

You seem to have forgotten to update keywords.c.

OK - works perfectly now :)

Now I'm going to play with making the SYMMERIC and ASYMMETRIC keywords less
reserved...

Can someone comment on my use of %prec BETWEEN? Is that still correct now
that we have the extra BETWEEN forms?

Chris

#4Gavin Sherry
swm@linuxworld.com.au
In reply to: Christopher Kings-Lynne (#3)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

On Wed, 10 Apr 2002, Christopher Kings-Lynne wrote:

Chris,

You seem to have forgotten to update keywords.c.

OK - works perfectly now :)

Now I'm going to play with making the SYMMERIC and ASYMMETRIC keywords less
reserved...

Can someone comment on my use of %prec BETWEEN? Is that still correct now
that we have the extra BETWEEN forms?

Yes. Have a look at the precedence table near the top of gram.y:

%left UNION EXCEPT
%left INTERSECT
%left JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
%left OR
%left AND
%right NOT
%right '='
%nonassoc '<' '>'
%nonassoc LIKE ILIKE
%nonassoc ESCAPE
%nonassoc OVERLAPS
%nonassoc BETWEEN
%nonassoc IN
%left POSTFIXOP /* dummy for postfix Op rules */

[...]

This is the order of precedence for rules which contain these
operators. For example, if an expression contains:

a AND b AND c

it is evaluated as:

((a AND b) AND c)

On the other hand:

a OR b AND c

is evaluated as:

((a OR b) AND c)

since OR has a lower order of precedence. Now, consider:

select 2 between asymmetric 3 and 1

Without the %prec BETWEEN

3 and 1

is given precedence over between. This will break your code.

Gavin

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christopher Kings-Lynne (#3)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

Can someone comment on my use of %prec BETWEEN? Is that still correct now
that we have the extra BETWEEN forms?

Looks fine. AFAICS we want all these forms to have the binding
precedence assigned to BETWEEN. If you don't do the %prec thing
then the productions will have the precedence of their rightmost
terminal symbol, ie, AND, ie, wrong.

regards, tom lane

#6Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#5)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

Can someone comment on my use of %prec BETWEEN? Is that still

correct now

that we have the extra BETWEEN forms?

Looks fine. AFAICS we want all these forms to have the binding
precedence assigned to BETWEEN. If you don't do the %prec thing
then the productions will have the precedence of their rightmost
terminal symbol, ie, AND, ie, wrong.

OK, I've proven that I cannot move the SYM/ASYM keywords anything lower than
totally reserved without causing shift/reduce errors. Is this acceptable?

Also, Tom (or anyone): in regards to your previous email, should I just go
back to using opt_symmetry to shorten the number of productions, since I
have to make them reserved words anyway?

Chris

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christopher Kings-Lynne (#6)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

Also, Tom (or anyone): in regards to your previous email, should I just go
back to using opt_symmetry to shorten the number of productions, since I
have to make them reserved words anyway?

Might as well. No point in writing more productions if it doesn't buy
anything.

BTW, I've forgotten whether your patch is purely syntactic or not,
but I'd really like to see someone fix things so that BETWEEN has its
own expression node tree type and is not expanded into some ugly
"A>=B and A<=C" equivalent. This would (a) allow it to be
reverse-listed reasonably, and (b) eliminate redundant evaluations of
the subexpressions.

regards, tom lane

#8Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#7)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

Also, Tom (or anyone): in regards to your previous email,

should I just go

back to using opt_symmetry to shorten the number of productions, since I
have to make them reserved words anyway?

Might as well. No point in writing more productions if it doesn't buy
anything.

Since it's really just two ways of writing the same thing, wouldn't bison
just produce the exact same C code? I'll rewrite it anyway for elegance,
but just wondering...

BTW, I've forgotten whether your patch is purely syntactic or not,
but I'd really like to see someone fix things so that BETWEEN has its
own expression node tree type and is not expanded into some ugly
"A>=B and A<=C" equivalent. This would (a) allow it to be
reverse-listed reasonably, and (b) eliminate redundant evaluations of
the subexpressions.

It is purely syntactic. Anyone want to give me a quick hint on how to make
a new node tree type for BETWEEN? What does reverse-listing mean as well?

Chris

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christopher Kings-Lynne (#8)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

Since it's really just two ways of writing the same thing, wouldn't bison
just produce the exact same C code? I'll rewrite it anyway for elegance,
but just wondering...

The emitted code might or might not be the same --- but duplicate or
near-duplicate chunks of source code are always best avoided, if only
from a maintenance perspective.

BTW, I've forgotten whether your patch is purely syntactic or not,
but I'd really like to see someone fix things so that BETWEEN has its
own expression node tree type and is not expanded into some ugly
"A>=B and A<=C" equivalent. This would (a) allow it to be
reverse-listed reasonably, and (b) eliminate redundant evaluations of
the subexpressions.

It is purely syntactic. Anyone want to give me a quick hint on how to make
a new node tree type for BETWEEN?

Try chasing the references to another extant expression node type,
perhaps NullTest. It's fairly straightforward, but tedious to teach
all the relevant places about it.

What does reverse-listing mean as well?

reverse-listing is what src/backend/utils/adt/ruleutils.c does: produce
something readable from an internal node tree. \d for a view, pg_dump,
and other useful things depend on this.

regards, tom lane

#10Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#9)
Make text output more generic

Hi,

I'm working on making the SHOW command dump its output as if it were a
select result.

Tom's declared the following as static ("private") methods?

static TextOutputState *begin_text_output(CommandDest dest, char *title);
static void do_text_output(TextOutputState *tstate, char *aline);
static void do_text_output_multiline(TextOutputState *tstate, char *text);
static void end_text_output(TextOutputState *tstate);

I should really move these off somewhere else and make them a bit more
global and generic. I will also use Joe's version (private email) that
should allow more columns in the output. What should I name these
functions? I notice a tendency towards TextDoOutput, TextDoOuputMultiline,
TextEndOutput sort of naming conventions for "global" functions.

Is this a good idea? Where I should put them?

Regards,

Chris

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christopher Kings-Lynne (#10)
Re: Make text output more generic

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

static TextOutputState *begin_text_output(CommandDest dest, char *title);
static void do_text_output(TextOutputState *tstate, char *aline);
static void do_text_output_multiline(TextOutputState *tstate, char *text);
static void end_text_output(TextOutputState *tstate);

I should really move these off somewhere else and make them a bit more
global and generic.

What's insufficiently generic about them for you?

regards, tom lane

#12Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#11)
Re: Make text output more generic

I should really move these off somewhere else and make them a bit more
global and generic.

What's insufficiently generic about them for you?

Well, at a _quick_ glance they're designed only for one column output...

Chris

#13Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christopher Kings-Lynne (#12)
Re: Make text output more generic

Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:

What's insufficiently generic about them for you?

Well, at a _quick_ glance they're designed only for one column output...

Well, exactly. These are intended to be a convenient interface for that
case. They're already sitting on top of generic tuple routines...

regards, tom lane

#14Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Christopher Kings-Lynne (#8)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

TODO updated:

* Add BETWEEN ASYMMETRIC/SYMMETRIC (Christopher)
* Christopher is Christopher Kings-Lynne <chriskl@familyhealth.com.au>

---------------------------------------------------------------------------

Christopher Kings-Lynne wrote:

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

Also, Tom (or anyone): in regards to your previous email,

should I just go

back to using opt_symmetry to shorten the number of productions, since I
have to make them reserved words anyway?

Might as well. No point in writing more productions if it doesn't buy
anything.

Since it's really just two ways of writing the same thing, wouldn't bison
just produce the exact same C code? I'll rewrite it anyway for elegance,
but just wondering...

BTW, I've forgotten whether your patch is purely syntactic or not,
but I'd really like to see someone fix things so that BETWEEN has its
own expression node tree type and is not expanded into some ugly
"A>=B and A<=C" equivalent. This would (a) allow it to be
reverse-listed reasonably, and (b) eliminate redundant evaluations of
the subexpressions.

It is purely syntactic. Anyone want to give me a quick hint on how to make
a new node tree type for BETWEEN? What does reverse-listing mean as well?

Chris

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@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
#15Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Bruce Momjian (#14)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

TODO updated:

* Add BETWEEN ASYMMETRIC/SYMMETRIC (Christopher)
* Christopher is Christopher Kings-Lynne <chriskl@familyhealth.com.au>

So should I go ahead and submit a patch for BETWEEN that adds SYMMETRY
support in the old-style code, and then at a later stage submit a patch that
makes BETWEEN a proper node?

Chris

#16Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Christopher Kings-Lynne (#15)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

Christopher Kings-Lynne wrote:

TODO updated:

* Add BETWEEN ASYMMETRIC/SYMMETRIC (Christopher)
* Christopher is Christopher Kings-Lynne <chriskl@familyhealth.com.au>

So should I go ahead and submit a patch for BETWEEN that adds SYMMETRY
support in the old-style code, and then at a later stage submit a patch that
makes BETWEEN a proper node?

Sure, I think that makes sense. The larger BETWEEN node code will be
tricky.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@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
#17Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Bruce Momjian (#16)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

So should I go ahead and submit a patch for BETWEEN that adds SYMMETRY
support in the old-style code, and then at a later stage submit

a patch that

makes BETWEEN a proper node?

Sure, I think that makes sense. The larger BETWEEN node code will be
tricky.

Question: Why have you created a special case for NOT BETWEEN? Wouldn't you
just need a BETWEEN node and the NOT node will handle the NOTing?

Or is it because BETWEEN isn't a node at the moment?

Chris

#18Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Christopher Kings-Lynne (#17)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

Christopher Kings-Lynne wrote:

So should I go ahead and submit a patch for BETWEEN that adds SYMMETRY
support in the old-style code, and then at a later stage submit

a patch that

makes BETWEEN a proper node?

Sure, I think that makes sense. The larger BETWEEN node code will be
tricky.

Question: Why have you created a special case for NOT BETWEEN? Wouldn't you
just need a BETWEEN node and the NOT node will handle the NOTing?

Or is it because BETWEEN isn't a node at the moment?

Well, looking at the grammar, I don't know how I could have gotten NOT
into that construction. There are two parameters separated by AND and I
didn't know how to do it.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@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
#19Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christopher Kings-Lynne (#15)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

So should I go ahead and submit a patch for BETWEEN that adds SYMMETRY
support in the old-style code, and then at a later stage submit a patch that
makes BETWEEN a proper node?

I'd prefer to do it in one step. I have not noticed any large
groundswell of demand for BETWEEN SYMMETRIC ... so I don't see a good
reason for implementing a stopgap version. (It would be a stopgap
mainly because the planner wouldn't recognize it as a range query.)

regards, tom lane

#20Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#19)
Re: BETWEEN SYMMETRIC/ASYMMETRIC

"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:

So should I go ahead and submit a patch for BETWEEN that adds SYMMETRY
support in the old-style code, and then at a later stage submit

a patch that

makes BETWEEN a proper node?

I'd prefer to do it in one step. I have not noticed any large
groundswell of demand for BETWEEN SYMMETRIC ... so I don't see a good
reason for implementing a stopgap version. (It would be a stopgap
mainly because the planner wouldn't recognize it as a range query.)

OK, I'll go for the whole change - just expect lots of questions :)

Chris