You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The return types of all methods on IAstPartialMapper include | nil. In what case might that be returned?
In my case I'm calling astMapper(...).statement(stmt) where stmt is a SelectFromStatement. Staring at AstDefaultMapper.selection, that returns assignChanged(val, ...) and assignChanged returns the same type as its first argument. So I fully expect to get a SelectFromStatement back. What's the nil there for? And if I do get a nil, how would I get at some more information about what went wrong?
It's a convention that for the whole mapper. If you override any method, and this method returns nil , then that means that this statement is not to be taken into account anymore.
For instance, lets say that you are coding a request proxy, and you want to exclude all queries that are not selects.
You will be able to do something like that:
constmapper=astMapper(map=>({statemsent: s=>s.type!=='select' ? null : map.select(s),}));consttransformed=mapper.statement(parseFirst(sql));if(!transformed){throwforbidden;}constnewSql=toSql.statement(transformed);// do whatever
This will not only filter statements like insert into xxx or truncate yyy, but will also remove statements which top-level seems to be a selection, but that might themselves contain non readonly statements like:
consttransformedmapper.statement(`with ids as (select id from t1) delete from t1 where 1=1 returning id`);// "transformed" will be null
Regarding the Statement instead of SelectFromStatement return type
Each method of the mapper returns the broadest type of statements that could be compatible with the input argument.
For instance, any expression mapper (like refs, binariess, etc) returns an Expr so you can have a mapper that transforms any kind of expression into another compatible expression.
Likewise, any top-level statement that returns data (select, with, delete, etc... are all able to return data) will be able to be mapped as any kind of data-returning statement.
That's what offers the most flexibility, while ensuring that types are guiding you to build correct statements.
It's a convention that for the whole mapper. If you override any method, and this method returns nil , then that means that this statement is not to be taken into account anymore.
You mean “this AST node is to not to be taken into account” (i.e. it should be skipped from the tree), right? Returning null doesn't annul the whole statement (except via the WITH default mapping, see below), just that node. So ...
This will not only filter statements like insert into xxx or truncate yyy, but will also remove statements which top-level seems to be a selection, but that might themselves contain non readonly statements like:
const transformed mapper.statement(`with ids as (select id from t1) delete from t1 where 1=1 returning id`);
// "transformed" will be null
Useful! Except I would want to still support WITH statements that don't contain non-read-only statements, like with ids as (select id from t1) select * from ids ... and the mapper above would reject those as well. To support read-only WITH-statements it should be (s.type !== 'select' && s.type !== 'with') ... and that still works for the “filter out non-read-only” use case, because the default mapper maps WITH-statements to null if their contained statements are mapped to null. This is illustrated by this test:
it('removes WITH node if one of its contained statements is removed',()=>{// create a mapperconstmapper=astMapper(map=>({statement: s=>{return(s.type!=='select'&&s.type!=='with') ? null : map.super().statement(s)},}));// process sqlconstkilled=mapper.statement(parse('with ids as (select id from t1) delete from t1 where 1=1 returning id'));assert.isNull(killed,'default mapper maps a WITH to null if its contained `in` statement gets mapped to null');constsurvived=mapper.statement(parse('with ids as (select id from t1) select * from ids'));assert.equal(toSql.statement(survived!),'WITH ids AS (SELECT id FROM t1 ) SELECT * FROM ids');});
This discussion was converted from issue #88 on June 20, 2022 08:50.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
The return types of all methods on
IAstPartialMapper
include| nil
. In what case might that be returned?In my case I'm calling
astMapper(...).statement(stmt)
wherestmt
is aSelectFromStatement
. Staring atAstDefaultMapper.selection
, that returnsassignChanged(val, ...)
andassignChanged
returns the same type as its first argument. So I fully expect to get aSelectFromStatement
back. What's thenil
there for? And if I do get anil
, how would I get at some more information about what went wrong?Beta Was this translation helpful? Give feedback.
All reactions