Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6703dff

Browse files
committed
Add more commentaries in core
Move up `jsonb_set_element` close to `jsonb_get_element`
1 parent3950944 commit6703dff

File tree

12 files changed

+135
-70
lines changed

12 files changed

+135
-70
lines changed

‎src/backend/catalog/heap.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ AddNewRelationType(const char *typeName,
978978
0,/* array dimensions for typBaseType */
979979
false,/* Type NOT NULL */
980980
InvalidOid,/* rowtypes never have a collation */
981-
InvalidOid);
981+
InvalidOid);/* typsubscription - none */
982982
}
983983

984984
/* --------------------------------
@@ -1246,7 +1246,7 @@ heap_create_with_catalog(const char *relname,
12461246
0,/* array dimensions for typBaseType */
12471247
false,/* Type NOT NULL */
12481248
InvalidOid,/* rowtypes never have a collation */
1249-
F_ARRAY_SUBSCRIPTION);
1249+
F_ARRAY_SUBSCRIPTION);/* array implementation */
12501250

12511251
pfree(relarrayname);
12521252
}

‎src/backend/commands/typecmds.c‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ DefineType(List *names, List *parameters)
642642
0,/* Array Dimensions of typbasetype */
643643
false,/* Type NOT NULL */
644644
collation,/* type's collation */
645-
subscriptionOid);
645+
subscriptionOid);/* subscription procedure */
646646
Assert(typoid==address.objectId);
647647

648648
/*
@@ -1075,7 +1075,7 @@ DefineDomain(CreateDomainStmt *stmt)
10751075
typNDims,/* Array dimensions for base type */
10761076
typNotNull,/* Type NOT NULL */
10771077
domaincoll,/* type's collation */
1078-
subscriptionProcedure);
1078+
subscriptionProcedure);/* subscription procedure */
10791079

10801080
/*
10811081
* Process constraints which refer to the domain ID returned by TypeCreate
@@ -1188,7 +1188,7 @@ DefineEnum(CreateEnumStmt *stmt)
11881188
0,/* Array dimensions of typbasetype */
11891189
false,/* Type NOT NULL */
11901190
InvalidOid,/* type's collation */
1191-
InvalidOid);
1191+
InvalidOid);/* typsubscription - none */
11921192

11931193
/* Enter the enum's values into pg_enum */
11941194
EnumValuesCreate(enumTypeAddr.objectId,stmt->vals);
@@ -1229,7 +1229,7 @@ DefineEnum(CreateEnumStmt *stmt)
12291229
0,/* Array dimensions of typbasetype */
12301230
false,/* Type NOT NULL */
12311231
InvalidOid,/* type's collation */
1232-
F_ARRAY_SUBSCRIPTION);
1232+
F_ARRAY_SUBSCRIPTION);/* array subscription implementation */
12331233

12341234
pfree(enumArrayName);
12351235

@@ -1529,7 +1529,7 @@ DefineRange(CreateRangeStmt *stmt)
15291529
0,/* Array dimensions of typbasetype */
15301530
false,/* Type NOT NULL */
15311531
InvalidOid,/* type's collation (ranges never have one) */
1532-
InvalidOid);
1532+
InvalidOid);/* typsubscription - none */
15331533
Assert(typoid==address.objectId);
15341534

15351535
/* Create the entry in pg_range */
@@ -1572,7 +1572,7 @@ DefineRange(CreateRangeStmt *stmt)
15721572
0,/* Array dimensions of typbasetype */
15731573
false,/* Type NOT NULL */
15741574
InvalidOid,/* typcollation */
1575-
F_ARRAY_SUBSCRIPTION);
1575+
F_ARRAY_SUBSCRIPTION);/* array subscription implementation */
15761576

15771577
pfree(rangeArrayName);
15781578

‎src/backend/executor/execQual.c‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,12 @@ static Datum ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate,
253253
/*----------
254254
* ExecEvalSubscriptionRef
255255
*
256-
* This function takes an SubscriptionRef and returns the extracted Datum
257-
* if it's a simple reference, or the modified containers value if it's
258-
* an containers assignment (i.e., containers element or slice insertion).
256+
* This function takes a SubscriptionRef, extracts all information required
257+
* for subscription and pass it to a particular subscription procedure,
258+
* specified for this data type. As a result the extracted Datum will be
259+
* returned if it's a simple reference, or the modified containers value if
260+
* it's an containers assignment (i.e., containers element or slice
261+
* insertion).
259262
*
260263
* NOTE: if we get a NULL result from a subscript expression, we return NULL
261264
* when it's an containers reference, or raise an error when it's an assignment.

‎src/backend/parser/parse_node.c‎

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,18 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno, int location)
201201

202202
/* NOTE: extra code for array type with isn't affect on other types
203203
* transformArrayType()
204-
*Identify the types involved in a subscripting operation
204+
*Identify the types involved in a subscripting operation for array
205205
*
206206
* On entry, arrayType/arrayTypmod identify the type of the input value
207207
* to be subscripted (which could be a domain type). These are modified
208208
* if necessary to identify the actual array type and typmod, and the
209209
* array's element type is returned. An error is thrown if the input isn't
210210
* an array type.
211+
*
212+
* NOTE: This part of type-specific code is not separated into type-specific
213+
* subscription procedure for now, but it does not affect on the whole logic,
214+
* since InvalidOid will be return in case of other types not an error.
215+
* An error will appears only if a subscription procedure is not defined.
211216
*/
212217
Oid
213218
transformArrayType(Oid*containerType,int32*containerTypmod)
@@ -257,29 +262,36 @@ transformArrayType(Oid *containerType, int32 *containerTypmod)
257262
*Transform container subscripting. This is used for both
258263
*container fetch and container assignment.
259264
*
260-
* In a container fetch, we are given a source container value and we produce an
261-
* expression that represents the result of extracting a single container element
262-
* or a container slice.
265+
* In a container fetch, we are given a source container value and we produce
266+
*anexpression that represents the result of extracting a single container
267+
*elementor a container slice.
263268
*
264269
* In a container assignment, we are given a destination container value plus a
265-
* source value that is to be assigned to a single element or a slice of
266-
*thatcontainer. We produce an expression that represents the new container value
270+
* source value that is to be assigned to a single element or a slice of that
271+
* container. We produce an expression that represents the new container value
267272
* with the source data inserted into the right part of the container.
268273
*
269-
* For both cases, if the source container is of a domain-over-container type,
270-
* the result is of the base container type or its element type; essentially,
271-
* we must fold a domain to its base type before applying subscripting.
272-
* (Note that int2vector and oidvector are treated as domains here.)
274+
* For both cases, this function contains only general subscription logic while
275+
* type-specific logic (e.g. type verifications and coersion) is placend in
276+
* separate procedure indicated by typsubscription. There is only one exception
277+
* for now about domain-over-container, if the source container is of a
278+
* domain-over-container type, the result is of the base container type or its
279+
* element type; essentially, we must fold a domain to its base type before
280+
* applying subscripting. (Note that int2vector and oidvector are treated as
281+
* domains here.) If domain verification failed we assume, that element type
282+
* must be the same as container type (e.g. in case of jsonb).
283+
* An error will appear in case if current container type doesn't have a
284+
* subscription procedure.
273285
*
274-
* pstateParse state
286+
* pstateParse state
275287
* containerBaseAlready-transformed expression for the container as a whole
276288
* containerTypeOID of container's datatype (should match type of containerBase,
277-
*or be the base type of containerBase's domain type)
278-
* elementTypeOID of container's element type (fetch withtransformcontainerType,
279-
*or pass InvalidOid to do it here)
289+
*or be the base type of containerBase's domain type)
290+
* elementTypeOID of container's element type (fetch withtransformArrayType,
291+
*or pass InvalidOid to do it here)
280292
* containerTypModtypmod for the container (which is also typmod for the elements)
281-
* indirectionUntransformed list of subscripts (must not be NIL)
282-
* assignFromNULL for container fetch, else transformed expression for source.
293+
* indirectionUntransformed list of subscripts (must not be NIL)
294+
* assignFromNULL for container fetch, else transformed expression for source.
283295
*/
284296

285297
SubscriptionRef*

‎src/backend/parser/parse_target.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ transformAssignmentIndirection(ParseState *pstate,
776776
}
777777

778778
/*
779-
* helper for transformAssignmentIndirection: processarray assignment
779+
* helper for transformAssignmentIndirection: processcontainer assignment
780780
*/
781781
staticNode*
782782
transformAssignmentSubscripts(ParseState*pstate,

‎src/backend/utils/adt/arrayfuncs.c‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6561,6 +6561,11 @@ isAssignmentIndirectionExpr(ExprState *exprstate)
65616561
return false;
65626562
}
65636563

6564+
/*
6565+
* Perform an actual data extraction or modification for the array
6566+
* subscription. As a result the extracted Datum or the modified containers
6567+
* value will be returned.
6568+
*/
65646569
Datum
65656570
array_subscription_evaluate(PG_FUNCTION_ARGS)
65666571
{
@@ -6722,6 +6727,13 @@ array_subscription_evaluate(PG_FUNCTION_ARGS)
67226727
sbstate->refelemalign);
67236728
}
67246729

6730+
/*
6731+
* Perform preparation for the array subscription, mostly type verification
6732+
* and coersion. This function produces an expression that represents the
6733+
* result of extracting a single container element/container slice or the new
6734+
* container value with the source data inserted into the right part of the
6735+
* container.
6736+
*/
67256737
Datum
67266738
array_subscription_prepare(PG_FUNCTION_ARGS)
67276739
{
@@ -6860,6 +6872,9 @@ array_subscription_prepare(PG_FUNCTION_ARGS)
68606872
PG_RETURN_POINTER(sbsref);
68616873
}
68626874

6875+
/*
6876+
* Handle array-type subscription logic.
6877+
*/
68636878
Datum
68646879
array_subscription(PG_FUNCTION_ARGS)
68656880
{

‎src/backend/utils/adt/jsonb.c‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,11 @@ to_jsonb(PG_FUNCTION_ARGS)
11491149
PG_RETURN_POINTER(JsonbValueToJsonb(res));
11501150
}
11511151

1152+
/*
1153+
* Do the actual conversion to jsonb for to_jsonb function. This logic is
1154+
* separated because it can be useful not only in here (e.g. we use it in
1155+
* jsonb subscription)
1156+
*/
11521157
JsonbValue*
11531158
to_jsonb_worker(Datumsource,Oidsource_type)
11541159
{

‎src/backend/utils/adt/jsonfuncs.c‎

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,32 @@ jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
13651365
}
13661366
}
13671367

1368+
Datum
1369+
jsonb_set_element(Datumjsonbdatum,Datum*path,intpath_len,
1370+
DatumsourceData,Oidsource_type)
1371+
{
1372+
Jsonb*jb=DatumGetJsonb(jsonbdatum);
1373+
JsonbValue*newval,
1374+
*res;
1375+
JsonbParseState*state=NULL;
1376+
JsonbIterator*it;
1377+
bool*path_nulls=palloc0(path_len*sizeof(bool));
1378+
1379+
newval=to_jsonb_worker(sourceData,source_type);
1380+
1381+
if (newval->type==jbvArray&&newval->val.array.rawScalar)
1382+
*newval=newval->val.array.elems[0];
1383+
1384+
it=JsonbIteratorInit(&jb->root);
1385+
1386+
res=setPath(&it,path,path_nulls,path_len,&state,0,
1387+
newval,JB_PATH_CREATE);
1388+
1389+
pfree(path_nulls);
1390+
1391+
PG_RETURN_JSONB(JsonbValueToJsonb(res));
1392+
}
1393+
13681394
/*
13691395
* SQL function json_array_length(json) -> int
13701396
*/
@@ -4033,12 +4059,17 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
40334059
if (op_type&JB_PATH_CREATE_OR_INSERT&& !done&&
40344060
level==path_len-1&&i==nelems-1)
40354061
{
4036-
(void)pushJsonbValue(st,WJB_ELEM,newval);
4062+
(void)pushJsonbValue(st,WJB_ELEM,new);
40374063
}
40384064
}
40394065
}
40404066
}
40414067

4068+
/*
4069+
* Perform an actual data extraction or modification for the jsonb
4070+
* subscription. As a result the extracted Datum or the modified containers
4071+
* value will be returned.
4072+
*/
40424073
Datum
40434074
jsonb_subscription_evaluate(PG_FUNCTION_ARGS)
40444075
{
@@ -4120,6 +4151,14 @@ jsonb_subscription_evaluate(PG_FUNCTION_ARGS)
41204151
false);
41214152
}
41224153

4154+
/*
4155+
* Perform preparation for the jsonb subscription. Since there are not any
4156+
* particular restrictions for this kind of subscription, we will verify that
4157+
* it is not a slice operation. This function produces an expression that
4158+
* represents the result of extracting a single container element or the new
4159+
* container value with the source data inserted into the right part of the
4160+
* container.
4161+
*/
41234162
Datum
41244163
jsonb_subscription_prepare(PG_FUNCTION_ARGS)
41254164
{
@@ -4168,6 +4207,9 @@ jsonb_subscription_prepare(PG_FUNCTION_ARGS)
41684207
PG_RETURN_POINTER(sbsref);
41694208
}
41704209

4210+
/*
4211+
* Handle jsonb-type subscription logic.
4212+
*/
41714213
Datum
41724214
jsonb_subscription(PG_FUNCTION_ARGS)
41734215
{
@@ -4183,29 +4225,3 @@ jsonb_subscription(PG_FUNCTION_ARGS)
41834225

41844226
elog(ERROR,"incorrect op_type for subscription function: %d",op_type);
41854227
}
4186-
4187-
Datum
4188-
jsonb_set_element(Datumjsonbdatum,Datum*path,intpath_len,
4189-
DatumsourceData,Oidsource_type)
4190-
{
4191-
Jsonb*jb=DatumGetJsonb(jsonbdatum);
4192-
JsonbValue*newval,
4193-
*res;
4194-
JsonbParseState*state=NULL;
4195-
JsonbIterator*it;
4196-
bool*path_nulls=palloc0(path_len*sizeof(bool));
4197-
4198-
newval=to_jsonb_worker(sourceData,source_type);
4199-
4200-
if (newval->type==jbvArray&&newval->val.array.rawScalar)
4201-
*newval=newval->val.array.elems[0];
4202-
4203-
it=JsonbIteratorInit(&jb->root);
4204-
4205-
res=setPath(&it,path,path_nulls,path_len,&state,0,
4206-
newval,JB_PATH_CREATE);
4207-
4208-
pfree(path_nulls);
4209-
4210-
PG_RETURN_JSONB(JsonbValueToJsonb(res));
4211-
}

‎src/include/catalog/pg_type.h‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO
198198
* collatable base types, possibly other OID for domains
199199
*/
200200
Oidtypcollation;
201+
202+
/*
203+
* Type specific subscription logic. If typsubscription is none, it means
204+
* that this type doesn't support subscription.
205+
*/
201206
regproctypsubscription;
202207

203208
#ifdefCATALOG_VARLEN/* variable-length fields start here */
@@ -224,7 +229,6 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO
224229
*/
225230
aclitemtypacl[1];
226231
#endif
227-
228232
}FormData_pg_type;
229233

230234
/* ----------------

‎src/include/nodes/execnodes.h‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,12 +657,21 @@ typedef struct SubscriptionRefExprState
657657
List*reflowerindexpr;
658658
ExprState*refexpr;
659659
ExprState*refassgnexpr;
660-
int16refattrlength;/* typlen ofarray type */
661-
int16refelemlength;/* typlen of thearray element type */
660+
int16refattrlength;/* typlen ofcontainer type */
661+
int16refelemlength;/* typlen of thecontainer element type */
662662
boolrefelembyval;/* is the element type pass-by-value? */
663663
charrefelemalign;/* typalign of the element type */
664664
}SubscriptionRefExprState;
665665

666+
/* ---------------------------------
667+
* Subscription exec information
668+
*
669+
* It contains all information which is required to perform type-specific data
670+
* extraction or modification. This information will be gathered in
671+
* `ExecEvalSubscriptionRef` function and passed to `typsubscription`
672+
* procedure.
673+
* ---------------------------------
674+
*/
666675
typedefstructSubscriptionExecData
667676
{
668677
ExprContext*xprcontext;/* econtext for subscription */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp