On 10/03/2021 05:30, Dmitry Yemanov wrote:
> 06.03.2021 14:53, Mark Rotteveel wrote:
>
>> Now I wonder, what would be necessary to introduce this alternative?
>> Would this be a matter of adding the right alternative and adding the
>> order by and offset/fetch info to the RseNode returned by the query
>> expression, or would more be needed?
>
> I'm afraid it's not gonna work.
>
> RseNode has dsqlOrder, but it's not used directly inside the parser
> (query_spec does not define ordering itself), so at the first glance it
> looks like it could be safely assigned in the new parser rules. However,
> implementation inside pass1.cpp moves the order node from SelectExprNode
> into underlying RseNode::dsqlOrder, so it might undo your work at the
> parser level in cases like this:
>
> ( select ... order by A ) order by B
>
> in this particular example it's OK, as nobody would see the ordering by
> A anyway. But it FIRST/ROWS/FETCH is applied too, ordering by A becomes
> a requirement.
>
> As for OFFSET/FETCH, things are even trickier. RseNode supports
> dsqlFirst/dsqlSkip, but they're used for legacy FIRST/SKIP inside
> query_spec. What to do in these cases:
>
> (select first 10 ...) fetch first 5 rows
> ( select ... fetch first 10 rows ) fetch first 5 rows
>
> where "10" may be replaced with "5". This looks safer than for the ORDER
> BY case but I'm not sure I can see all the subsequences.
>
> Perhaps query_term should return SelectExprNode* and the new parser
> rules define new SelectExprNode with querySpec/orderClause/rowsClause
> set up based on select_expr_body/order_clause_opt/rows_clause. But I'm
> pretty sure some code places are not prepared to see query_term as
> SelectExprNode*.
>
I did some tests and attached is a patch (v3).
It introduces conflicts which I didn't looked yet. Looks like it's with
derived tables support.
It allows this funny statement:
(select * from t);
If I'm looking in the standard correctly, at least from syntax rules it
should be allowed. :)
After reading your examples again, perhaps you knew about it. :)
Adriano
diff --git a/src/dsql/parse.y b/src/dsql/parse.y
index e2a4070b73..436609d201 100644
--- a/src/dsql/parse.y
+++ b/src/dsql/parse.y
@@ -5072,9 +5072,36 @@ select_expr_body
}
;
-%type <rseNode> query_term
+%type <recSourceNode> query_term
query_term
+ : query_primary
+ ;
+
+%type <recSourceNode> query_primary
+query_primary
: query_spec
+ { $$ = $1; }
+ | '(' select_expr_body order_clause result_offset_clause fetch_first_clause ')'
+ {
+ if ($3 || $4 || $5)
+ {
+ SelectExprNode* node = newNode<SelectExprNode>();
+ node->querySpec = $2;
+ node->orderClause = $3;
+
+ if ($4 || $5)
+ {
+ RowsClause* rowsNode = newNode<RowsClause>();
+ rowsNode->skip = $4;
+ rowsNode->length = $5;
+ node->rowsClause = rowsNode;
+ }
+
+ $$ = node;
+ }
+ else
+ $$ = $2;
+ }
;
%type <rseNode> query_spec
Firebird-Devel mailing list, web interface at
https://lists.sourceforge.net/lists/listinfo/firebird-devel