Skip to content

Commit

Permalink
Merge pull request #207 from cwida/kleene-star-followup
Browse files Browse the repository at this point in the history
Kleene star followup
  • Loading branch information
Dtenwolde authored Jan 13, 2025
2 parents c380346 + 5661189 commit 5e5dc9d
Show file tree
Hide file tree
Showing 5 changed files with 20,077 additions and 20,138 deletions.
81 changes: 22 additions & 59 deletions third_party/libpg_query/grammar/statements/pgq.y
Original file line number Diff line number Diff line change
Expand Up @@ -762,83 +762,46 @@ FullElementSpec:

/* we allow spaces inside the arrows */
Arrow:
'-'
{ $$ = "-"; }
ArrowRight
{ $$ = $1; }
|
'<' LAMBDA_ARROW
{ $$ = "<->"; }
|
'<' '-' '>'
{ $$ = "<->"; }
|
'<' '-'
{ $$ = "<-"; }
|
;

ArrowRight:
LAMBDA_ARROW
{ $$ = "->"; }
{ $$ = "->"; }
|
'-' '>'
{ $$ = "->"; }
|
'<' LAMBDA_ARROW
{ $$ = "<->"; }
{ $$ = "->"; }
|
'<' '-' '>'
{ $$ = "<->"; }
|
Op
{ /* DDB lexer may concatenate an arrow with + or * into an "operator" */
char *op = $1, *ok = NULL;
/* only <-, <->, -, -> are ok */
if (op[0] == '<') op++; /* also accept <-> */
if (op[0] == '-') {
ok = op + 1 + (op[1] == '>');
}
/* it may optionally be followed by a single * or + */
if (!ok || (ok[0] && ((ok[0] != '*' && ok[0] != '+') || ok[1]))) {
char msg[128];
snprintf(msg, 128, "PGQ expected an arrow instead of %s operator.", $1);
parser_yyerror(msg);
}
$$ = $1;
}
'-'
{ $$ = "-"; }
;

ArrowLeft:
'-' '['
{ $$ = "-"; }
{ $$ = "-"; }
|
'<' '-' '['
{ $$ = "<-"; }
;

ArrowKleeneOptional:
Arrow KleeneOptional
{
PGSubPath *p = (PGSubPath*) $2;
char *op = $1;
int len = strlen(op);
int plus = (op[len-1] == '+');
int star = (op[len-1] == '*');
if (plus || star) { /* + or * was glued to the end of the arrow */
if (!p->single_bind || p->lower != 1 || p-> upper != 1) {
parser_yyerror("PGQ cannot accept + or * followed by another quantifier.");
} else {
p->single_bind = 0;
p->lower = plus;
p->upper = (1<<30);
}
}
p->path = (PGList*) op; /* return the arrow temporarily in 'path'.. */
$$ = (PGNode*) p;
}
;

EdgePattern:
ArrowLeft FullElementSpec ']' ArrowKleeneOptional
ArrowLeft FullElementSpec ']' ArrowRight KleeneOptional
{
PGSubPath *p = (PGSubPath*) $4;
PGSubPath *p = (PGSubPath*) $5;
char *left = $1;
char *dash = (char*) p->path;
char *dash = (char*) $4;
PGPathInfo* i = (PGPathInfo*) $2;
PGPathElement *n = makeNode(PGPathElement);
if (dash[0] == '<') { /* ArrowKleeneOptional accepts <- but that is not ok here */
parser_yyerror("PGQ cannot accept < after ] edge pattern closing.");
}
n->match_type = (dash[1] == '>')?
((left[0] == '<')?PG_MATCH_EDGE_LEFT_RIGHT:PG_MATCH_EDGE_RIGHT):
((left[0] == '<')?PG_MATCH_EDGE_LEFT:PG_MATCH_EDGE_ANY);
Expand All @@ -856,10 +819,10 @@ EdgePattern:
}
}
|
ArrowKleeneOptional
Arrow KleeneOptional
{
PGSubPath *p = (PGSubPath*) $1;
char *left = (char*) p->path;
PGSubPath *p = (PGSubPath*) $2;
char *left = (char*) $1;
PGPathElement *n = makeNode(PGPathElement);;
char *dash = left + (left[0] == '<');
n->label_expr = NULL;
Expand Down
2 changes: 1 addition & 1 deletion third_party/libpg_query/grammar/types/pgq.yh
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
%type <node> OrLabelExpression
%type <node> LabelExpressionOptional
%type <str> Arrow
%type <str> ArrowRight
%type <str> ArrowLeft
%type <node> ArrowKleeneOptional
%type <str> VariableOptional
%type <node> FullElementSpec
%type <list> EdgePattern
Expand Down
6 changes: 6 additions & 0 deletions third_party/libpg_query/scan.l
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,12 @@ other .
nchars = slashstar - yytext;
}

/* for PGQ it is confusing if + or * is glued to an arrow (<-> -> <-) or end of it (-> > -) */
char* prefix_first = yytext + (yytext[0] == '<'); /* skip: reduces prefix possibilities to (-> > -) */
char* prefix_last = yytext + nchars - (1 + (yytext[nchars-1] == '*' || yytext[nchars-1] == '+'));
if ((prefix_last == prefix_first+1 && *prefix_first == '-' && *prefix_last == '>') ||
(prefix_last == prefix_first && (*prefix_first == '-' || *prefix_first == '>'))) nchars = 1; /* break it up */

/*
* For SQL compatibility, '+' and '-' cannot be the
* last char of a multi-char operator unless the operator
Expand Down
Loading

0 comments on commit 5e5dc9d

Please sign in to comment.