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

Commitdfe6ac2

Browse files
committed
Allow to store record type as a scalar variable
1 parentd00692b commitdfe6ac2

File tree

4 files changed

+95
-39
lines changed

4 files changed

+95
-39
lines changed

‎expected/pg_variables.out

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,27 @@ SELECT package FROM pgv_stats() WHERE package = 'vars4';
759759
---------
760760
(0 rows)
761761

762+
-- Record variables as scalar
763+
SELECT pgv_set('vars5', 'r1', row(1, 'str11'));
764+
pgv_set
765+
---------
766+
767+
(1 row)
768+
769+
SELECT pgv_get('vars5', 'r1', NULL::record);
770+
pgv_get
771+
-----------
772+
(1,str11)
773+
(1 row)
774+
775+
SELECT pgv_set('vars5', 'r1', row(1, 'str11'), true); -- fail
776+
ERROR: variable "r1" already created as NOT TRANSACTIONAL
777+
SELECT pgv_insert('vars5', 'r1', row(1, 'str11')); -- fail
778+
ERROR: "r1" isn't a record variable
779+
SELECT pgv_select('vars5', 'r1'); -- fail
780+
ERROR: "r1" isn't a record variable
781+
SELECT pgv_get('vars3', 'r1', NULL::record); -- fail
782+
ERROR: "r1" isn't a scalar variable
762783
-- Manipulate variables
763784
SELECT * FROM pgv_list() order by package, name;
764785
package | name | is_transactional
@@ -786,15 +807,17 @@ SELECT * FROM pgv_list() order by package, name;
786807
vars2 | j2 | f
787808
vars3 | r1 | f
788809
vars3 | r2 | f
789-
(23 rows)
810+
vars5 | r1 | f
811+
(24 rows)
790812

791813
SELECT package FROM pgv_stats() order by package;
792814
package
793815
---------
794816
vars
795817
vars2
796818
vars3
797-
(3 rows)
819+
vars5
820+
(4 rows)
798821

799822
SELECT pgv_remove('vars', 'int3');
800823
ERROR: unrecognized variable "int3"
@@ -849,7 +872,8 @@ SELECT * FROM pgv_list() order by package, name;
849872
vars | tstzNULL | f
850873
vars3 | r1 | f
851874
vars3 | r2 | f
852-
(20 rows)
875+
vars5 | r1 | f
876+
(21 rows)
853877

854878
SELECT pgv_free();
855879
pgv_free

‎pg_variables.c

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,10 @@ static void ensurePackagesHashExists(void);
5050
staticvoidgetKeyFromName(text*name,char*key);
5151

5252
staticPackage*getPackageByName(text*name,boolcreate,boolstrict);
53-
staticVariable*getVariableInternal(Package*package,
54-
text*name,Oidtypid,
55-
boolstrict);
56-
staticVariable*createVariableInternal(Package*package,
57-
text*name,Oidtypid,
58-
boolis_transactional);
53+
staticVariable*getVariableInternal(Package*package,text*name,
54+
Oidtypid,boolis_record,boolstrict);
55+
staticVariable*createVariableInternal(Package*package,text*name,Oidtypid,
56+
boolis_record,boolis_transactional);
5957
staticvoidremovePackageInternal(Package*package);
6058
staticvoidresetVariablesCache(boolwith_package);
6159

@@ -65,7 +63,7 @@ static void releaseSavepoint(TransObject *object, TransObjectType type);
6563
staticvoidrollbackSavepoint(TransObject*object,TransObjectTypetype);
6664

6765
staticvoidcopyValue(VarState*src,VarState*dest,Variable*destVar);
68-
staticvoidfreeValue(VarState*varstate,Oidtypid);
66+
staticvoidfreeValue(VarState*varstate,boolis_record);
6967
staticvoidremoveState(TransObject*object,TransObjectTypetype,
7068
TransState*stateToDelete);
7169
staticboolisObjectChangedInCurrentTrans(TransObject*object);
@@ -160,7 +158,7 @@ variable_set(text *package_name, text *var_name,
160158
ScalarVar*scalar;
161159

162160
package=getPackageByName(package_name, true, false);
163-
variable=createVariableInternal(package,var_name,typid,
161+
variable=createVariableInternal(package,var_name,typid, false,
164162
is_transactional);
165163

166164
scalar=&(GetActualValue(variable).scalar);
@@ -197,7 +195,7 @@ variable_get(text *package_name, text *var_name,
197195
return0;
198196
}
199197

200-
variable=getVariableInternal(package,var_name,typid,strict);
198+
variable=getVariableInternal(package,var_name,typid,false,strict);
201199

202200
if (variable==NULL)
203201
{
@@ -343,7 +341,7 @@ variable_insert(PG_FUNCTION_ARGS)
343341
VARSIZE_ANY_EXHDR(var_name))!=0)
344342
{
345343
variable=createVariableInternal(package,var_name,RECORDOID,
346-
is_transactional);
344+
true,is_transactional);
347345
LastVariable=variable;
348346
}
349347
else
@@ -455,7 +453,8 @@ variable_update(PG_FUNCTION_ARGS)
455453
strncmp(VARDATA_ANY(var_name),GetName(LastVariable),
456454
VARSIZE_ANY_EXHDR(var_name))!=0)
457455
{
458-
variable=getVariableInternal(package,var_name,RECORDOID, true);
456+
variable=getVariableInternal(package,var_name,RECORDOID, true,
457+
true);
459458
LastVariable=variable;
460459
}
461460
else
@@ -543,7 +542,8 @@ variable_delete(PG_FUNCTION_ARGS)
543542
strncmp(VARDATA_ANY(var_name),GetName(LastVariable),
544543
VARSIZE_ANY_EXHDR(var_name))!=0)
545544
{
546-
variable=getVariableInternal(package,var_name,RECORDOID, true);
545+
variable=getVariableInternal(package,var_name,RECORDOID, true,
546+
true);
547547
LastVariable=variable;
548548
}
549549
else
@@ -592,7 +592,8 @@ variable_select(PG_FUNCTION_ARGS)
592592
var_name=PG_GETARG_TEXT_PP(1);
593593

594594
package=getPackageByName(package_name, false, true);
595-
variable=getVariableInternal(package,var_name,RECORDOID, true);
595+
variable=getVariableInternal(package,var_name,RECORDOID, true,
596+
true);
596597

597598
record=&(GetActualValue(variable).record);
598599

@@ -667,7 +668,7 @@ variable_select_by_value(PG_FUNCTION_ARGS)
667668
}
668669

669670
package=getPackageByName(package_name, false, true);
670-
variable=getVariableInternal(package,var_name,RECORDOID, true);
671+
variable=getVariableInternal(package,var_name,RECORDOID, true, true);
671672

672673
if (!value_is_null)
673674
check_record_key(variable,value_type);
@@ -736,7 +737,8 @@ variable_select_by_values(PG_FUNCTION_ARGS)
736737
var_name=PG_GETARG_TEXT_PP(1);
737738

738739
package=getPackageByName(package_name, false, true);
739-
variable=getVariableInternal(package,var_name,RECORDOID, true);
740+
variable=getVariableInternal(package,var_name,RECORDOID, true,
741+
true);
740742

741743
check_record_key(variable,ARR_ELEMTYPE(values));
742744

@@ -870,7 +872,7 @@ remove_variable(PG_FUNCTION_ARGS)
870872
var_name=PG_GETARG_TEXT_PP(1);
871873

872874
package=getPackageByName(package_name, false, true);
873-
variable=getVariableInternal(package,var_name,InvalidOid, true);
875+
variable=getVariableInternal(package,var_name,InvalidOid,false,true);
874876

875877
/* Add package to changes list, so we can remove it if it is empty */
876878
if (!isObjectChangedInCurrentTrans(&package->transObject))
@@ -908,7 +910,6 @@ remove_package(PG_FUNCTION_ARGS)
908910
{
909911
Package*package;
910912
text*package_name;
911-
charkey[NAMEDATALEN];
912913

913914
if (PG_ARGISNULL(0))
914915
ereport(ERROR,
@@ -1430,7 +1431,8 @@ getPackageByName(text *name, bool create, bool strict)
14301431
* flag 'is_transactional' of this variable is unknown.
14311432
*/
14321433
staticVariable*
1433-
getVariableInternal(Package*package,text*name,Oidtypid,boolstrict)
1434+
getVariableInternal(Package*package,text*name,Oidtypid,boolis_record,
1435+
boolstrict)
14341436
{
14351437
Variable*variable;
14361438
charkey[NAMEDATALEN];
@@ -1447,15 +1449,25 @@ getVariableInternal(Package *package, text *name, Oid typid, bool strict)
14471449
/* Check variable type */
14481450
if (found)
14491451
{
1450-
if (typid!=InvalidOid&&variable->typid!=typid)
1452+
if (typid!=InvalidOid)
14511453
{
1452-
char*var_type=DatumGetCString(DirectFunctionCall1(regtypeout,
1453-
ObjectIdGetDatum(variable->typid)));
1454+
if (variable->typid!=typid)
1455+
{
1456+
char*var_type=DatumGetCString(
1457+
DirectFunctionCall1(regtypeout,
1458+
ObjectIdGetDatum(variable->typid)));
14541459

1455-
ereport(ERROR,
1456-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1457-
errmsg("variable \"%s\" requires \"%s\" value",
1458-
key,var_type)));
1460+
ereport(ERROR,
1461+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1462+
errmsg("variable \"%s\" requires \"%s\" value",
1463+
key,var_type)));
1464+
}
1465+
1466+
if (variable->is_record!=is_record)
1467+
ereport(ERROR,
1468+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1469+
errmsg("\"%s\" isn't a %s variable",
1470+
key,is_record ?"record" :"scalar")));
14591471
}
14601472
if (!GetActualState(variable)->is_valid&&strict)
14611473
ereport(ERROR,
@@ -1475,11 +1487,11 @@ getVariableInternal(Package *package, text *name, Oid typid, bool strict)
14751487

14761488
/*
14771489
* Create a variable or return a pointer to existing one.
1478-
* Function is useful to set new value to variable and
1479-
*flag 'is_transactional'is known.
1490+
* Function is useful to set new value to variable and flag 'is_transactional'
1491+
* is known.
14801492
*/
14811493
staticVariable*
1482-
createVariableInternal(Package*package,text*name,Oidtypid,
1494+
createVariableInternal(Package*package,text*name,Oidtypid,boolis_record,
14831495
boolis_transactional)
14841496
{
14851497
Variable*variable;
@@ -1521,6 +1533,12 @@ createVariableInternal(Package *package, text *name, Oid typid,
15211533
key,var_type)));
15221534
}
15231535

1536+
if (variable->is_record!=is_record)
1537+
ereport(ERROR,
1538+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1539+
errmsg("\"%s\" isn't a %s variable",
1540+
key,is_record ?"record" :"scalar")));
1541+
15241542
/*
15251543
* Savepoint must be created when variable changed in current
15261544
* transaction. For each transaction level there should be a
@@ -1540,14 +1558,15 @@ createVariableInternal(Package *package, text *name, Oid typid,
15401558
/* Variable entry was created, so initialize new variable. */
15411559
variable->typid=typid;
15421560
variable->package=package;
1561+
variable->is_record=is_record;
15431562
variable->is_transactional=is_transactional;
15441563

15451564
dlist_init(GetStateStorage(variable));
15461565
varState=MemoryContextAllocZero(pack_hctx(package,is_transactional),
15471566
sizeof(VarState));
15481567

15491568
dlist_push_head(GetStateStorage(variable),&varState->state.node);
1550-
if (typid!=RECORDOID)
1569+
if (!variable->is_record)
15511570
{
15521571
ScalarVar*scalar=&(varState->value.scalar);
15531572

@@ -1578,7 +1597,7 @@ copyValue(VarState *src, VarState *dest, Variable *destVar)
15781597

15791598
oldcxt=MemoryContextSwitchTo(destVar->package->hctxTransact);
15801599

1581-
if (destVar->typid==RECORDOID)
1600+
if (destVar->is_record)
15821601
/* copy record value */
15831602
{
15841603
HASH_SEQ_STATUSrstat;
@@ -1610,19 +1629,17 @@ copyValue(VarState *src, VarState *dest, Variable *destVar)
16101629
}
16111630

16121631
staticvoid
1613-
freeValue(VarState*varstate,Oidtypid)
1632+
freeValue(VarState*varstate,boolis_record)
16141633
{
1615-
if (typid==RECORDOID&&varstate->value.record.hctx)
1634+
if (is_record&&varstate->value.record.hctx)
16161635
{
16171636
/* All records will be freed */
16181637
MemoryContextDelete(varstate->value.record.hctx);
16191638
}
1620-
elseif (varstate->value.scalar.typbyval== false&&
1639+
elseif (!is_record&&varstate->value.scalar.typbyval== false&&
16211640
varstate->value.scalar.is_null== false&&
16221641
varstate->value.scalar.value)
1623-
{
16241642
pfree(DatumGetPointer(varstate->value.scalar.value));
1625-
}
16261643
}
16271644

16281645
staticvoid
@@ -1632,7 +1649,7 @@ removeState(TransObject *object, TransObjectType type, TransState *stateToDelete
16321649
{
16331650
Variable*var= (Variable*)object;
16341651

1635-
freeValue((VarState*)stateToDelete,var->typid);
1652+
freeValue((VarState*)stateToDelete,var->is_record);
16361653
}
16371654
dlist_delete(&stateToDelete->node);
16381655
pfree(stateToDelete);

‎pg_variables.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ typedef struct Variable
101101
TransObjecttransObject;
102102
Package*package;
103103
Oidtypid;
104+
/*
105+
* We need an additional flag to determine variable's type since we can
106+
* store record type DATUM within scalar variable
107+
*/
108+
boolis_record;
104109

105110
/*
106111
* The flag determines the further behavior of the variable. Can be

‎sql/pg_variables.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,16 @@ SELECT pgv_insert('vars4', 'r2', row(1, 'str1', 'str2'));
215215
SELECT pgv_remove('vars4','r2');
216216
SELECT packageFROM pgv_stats()WHERE package='vars4';
217217

218+
-- Record variables as scalar
219+
SELECT pgv_set('vars5','r1', row(1,'str11'));
220+
SELECT pgv_get('vars5','r1',NULL::record);
221+
SELECT pgv_set('vars5','r1', row(1,'str11'), true);-- fail
222+
223+
SELECT pgv_insert('vars5','r1', row(1,'str11'));-- fail
224+
SELECT pgv_select('vars5','r1');-- fail
225+
226+
SELECT pgv_get('vars3','r1',NULL::record);-- fail
227+
218228
-- Manipulate variables
219229
SELECT*FROM pgv_list()order by package, name;
220230
SELECT packageFROM pgv_stats()order by package;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp