Re: Extract numeric filed in JSONB more effectively

Поиск
Список
Период
Сортировка
От Andy Fan
Тема Re: Extract numeric filed in JSONB more effectively
Дата
Msg-id CAKU4AWqQ8QQ=QABALQMAUaAkT3BaReujJgPm3QOqDHxk_=abnA@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Extract numeric filed in JSONB more effectively  (Chapman Flack <chap@anastigmatix.net>)
Ответы Re: Extract numeric filed in JSONB more effectively  (Andy Fan <zhihui.fan1213@gmail.com>)
Список pgsql-hackers


On Thu, Sep 14, 2023 at 5:18 AM Chapman Flack <chap@anastigmatix.net> wrote:
On 2023-09-04 10:35, Andy Fan wrote:
>   v13 attached.  Changes includes:
>
> 1.  fix the bug Jian provides.
> 2.  reduce more code duplication without DirectFunctionCall.
> 3.  add the overlooked  jsonb_path_query and jsonb_path_query_first as
> candidates

Apologies for the delay. I like the way this is shaping up.

This is a great signal:) 
 
 
My first comment will be one that may be too large for this patch
(and too large to rest on my opinion alone); that's why I'm making
it first.

It seems at first a minor point: to me it feels like a wart to have
to pass jsonb_finish_numeric (and *only* jsonb_finish_numeric) a type
oid reflecting the target type of a cast that's going to be applied
*after jsonb_finish_numeric has done its work*, and only for the
purpose of generating a message if the jsonb type *isn't numeric*,
but saying "cannot cast to" (that later target type) instead.

I understand this is done to exactly match the existing behavior,
so what makes this a larger issue is I'm not convinced the existing
behavior is good. Therefore I'm not convinced that bending over
backward to preserve it is good.

I hesitated to do so, but I'm thinking if any postgresql user uses
some code like   if (errMsg.equals('old-error-message')),  and if we
change the error message, the application will be broken. I agree 
with the place for the error message,  IIUC,  you intend to choose
not compatible with the old error message? 

What's not good: the places a message from cannotCastJsonbValue
are produced, there has been no attempt yet to cast anything.
The message purely tells you about whether you have the kind
of jsonb node you think you have (and array, bool, null, numeric,
object, string are the only kinds of those). If you're wrong
about what kind of jsonb node it is, you get this message.
If you're right about the kind of node, you don't get this
message, regardless of whether its value can be cast to the
later target type. For example, '32768'::jsonb::int2 produces
ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE "smallint out of range"
but that message comes from the actual int2 cast.

IMV, what the "cannot cast jsonb foo to type %s" message really
means is "jsonb foo where jsonb bar is required" and that's what
it should say, and that message depends on nothing about any
future plans for what will be done to the jsonb bar, so it can
be produced without needing any extra information to be passed.

I'm also not convinced ERRCODE_INVALID_PARAMETER_VALUE is a
good errcode for that message (whatever the wording). I do not
see much precedent elsewhere in the code for using
INVALID_PARAMETER_VALUE to signal this kind of "data value
isn't what you think it is" condition. Mostly it is used
when checking the kinds of parameters passed to a function to
indicate what it should do.

There seem to be several more likely choices for an errcode
there in the 2203x range.

But I understand that issue is not with this patch so much
as with preexisting behavior, and because it's preexisting,
there can be sound arguments against changing it.  

But if that preexisting message could be changed, it would
eliminate the need for an unpleasing wart here.

Other notes are more minor:

+               else
+                       /* not the desired pattern. */
+                       PG_RETURN_POINTER(fexpr);
...
+
+               if (!OidIsValid(new_func_id))
+                       PG_RETURN_POINTER(fexpr);
...
+                       default:
+                               PG_RETURN_POINTER(fexpr);

If I am reading supportnodes.h right, returning NULL is
sufficient to say no transformation is needed.

I double confirmed you are right here.  
Changed it to PG_RETURN_POINT(null);   here in the next version. 

+               FuncExpr        *fexpr = palloc0(sizeof(FuncExpr));
...
+               memcpy(fexpr, req->fcall, sizeof(FuncExpr));

Is the shallow copy necessary? If so, a comment explaining why
might be apropos. Because the copy is shallow, if there is any
concern about the lifespan of req->fcall, would there not be a
concern about its children?

All the interesting parts in the input FuncExpr are heap based, 
but the FuncExpr itself is stack based (I'm not sure why the fact
works like this),  Also based on my previously understanding, I
need to return a FuncExpr original even if the function can't be 
simplified, so I made a shallow copy.  There will be no copy at 
all in the following version since I returned NULL in such a case. 
 
Is there a reason not to transform the _tz flavors of
jsonb_path_query and jsonb_path-query_first?

I misunderstood the _tz flavors return timestamp,  after some deep
reading of these functions, they just work at the comparisons part.
so I will add them in the following version.  
 

-       JsonbValue *v;
-       JsonbValue      vbuf;
+       JsonbValue      *v;
...
+       int i;
        JsonbValue *jbvp = NULL;
-       int                     i;

Sometimes it's worth looking over a patch for changes like these,
and reverting such whitespace or position changes, if they aren't
things you want a reviewer to be squinting at. :)

Yes, I  look over my patch carefully before sending it out usually,
but this is an oversight. 

Lastly,  do you have any idea about the function naming as Jian & I
discussed at [1]?


--
Best Regards
Andy Fan

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Krishnakumar R
Дата:
Сообщение: Small patch modifying variable name to reflect the logic involved
Следующее
От: Krishnakumar R
Дата:
Сообщение: Fixup the variable name to indicate the WAL record reservation status.