LCOV - differential code coverage report
Current view: top level - src/backend/catalog - pg_attrdef.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 96.2 % 130 125 2 2 1 2 54 3 66 2 52 5
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 5 5 4 1 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 96.2 % 130 125 2 2 1 2 54 3 66 2 52
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 55.6 % 9 5 4 1 4

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * pg_attrdef.c
                                  4                 :  *    routines to support manipulation of the pg_attrdef relation
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  *
                                 10                 :  * IDENTIFICATION
                                 11                 :  *    src/backend/catalog/pg_attrdef.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : #include "postgres.h"
                                 16                 : 
                                 17                 : #include "access/genam.h"
                                 18                 : #include "access/relation.h"
                                 19                 : #include "access/table.h"
                                 20                 : #include "catalog/catalog.h"
                                 21                 : #include "catalog/dependency.h"
                                 22                 : #include "catalog/indexing.h"
                                 23                 : #include "catalog/objectaccess.h"
                                 24                 : #include "catalog/pg_attrdef.h"
                                 25                 : #include "executor/executor.h"
                                 26                 : #include "optimizer/optimizer.h"
                                 27                 : #include "utils/array.h"
                                 28                 : #include "utils/builtins.h"
                                 29                 : #include "utils/fmgroids.h"
                                 30                 : #include "utils/rel.h"
                                 31                 : #include "utils/syscache.h"
                                 32                 : 
                                 33                 : 
                                 34                 : /*
                                 35                 :  * Store a default expression for column attnum of relation rel.
                                 36                 :  *
                                 37                 :  * Returns the OID of the new pg_attrdef tuple.
                                 38                 :  *
                                 39                 :  * add_column_mode must be true if we are storing the default for a new
                                 40                 :  * attribute, and false if it's for an already existing attribute. The reason
                                 41                 :  * for this is that the missing value must never be updated after it is set,
                                 42                 :  * which can only be when a column is added to the table. Otherwise we would
                                 43                 :  * in effect be changing existing tuples.
                                 44                 :  */
                                 45                 : Oid
  384 tgl                        46 CBC        1717 : StoreAttrDefault(Relation rel, AttrNumber attnum,
                                 47                 :                  Node *expr, bool is_internal, bool add_column_mode)
                                 48                 : {
                                 49                 :     char       *adbin;
                                 50                 :     Relation    adrel;
                                 51                 :     HeapTuple   tuple;
                                 52                 :     Datum       values[4];
                                 53                 :     static bool nulls[4] = {false, false, false, false};
                                 54                 :     Relation    attrrel;
                                 55                 :     HeapTuple   atttup;
                                 56                 :     Form_pg_attribute attStruct;
                                 57                 :     char        attgenerated;
                                 58                 :     Oid         attrdefOid;
                                 59                 :     ObjectAddress colobject,
                                 60                 :                 defobject;
                                 61                 : 
                                 62            1717 :     adrel = table_open(AttrDefaultRelationId, RowExclusiveLock);
                                 63                 : 
                                 64                 :     /*
                                 65                 :      * Flatten expression to string form for storage.
                                 66                 :      */
                                 67            1717 :     adbin = nodeToString(expr);
                                 68                 : 
                                 69                 :     /*
                                 70                 :      * Make the pg_attrdef entry.
                                 71                 :      */
                                 72            1717 :     attrdefOid = GetNewOidWithIndex(adrel, AttrDefaultOidIndexId,
                                 73                 :                                     Anum_pg_attrdef_oid);
                                 74            1717 :     values[Anum_pg_attrdef_oid - 1] = ObjectIdGetDatum(attrdefOid);
                                 75            1717 :     values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel);
                                 76            1717 :     values[Anum_pg_attrdef_adnum - 1] = attnum;
                                 77            1717 :     values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
                                 78                 : 
                                 79            1717 :     tuple = heap_form_tuple(adrel->rd_att, values, nulls);
                                 80            1717 :     CatalogTupleInsert(adrel, tuple);
                                 81                 : 
                                 82            1717 :     defobject.classId = AttrDefaultRelationId;
                                 83            1717 :     defobject.objectId = attrdefOid;
                                 84            1717 :     defobject.objectSubId = 0;
                                 85                 : 
                                 86            1717 :     table_close(adrel, RowExclusiveLock);
                                 87                 : 
                                 88                 :     /* now can free some of the stuff allocated above */
                                 89            1717 :     pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
                                 90            1717 :     heap_freetuple(tuple);
                                 91            1717 :     pfree(adbin);
                                 92                 : 
                                 93                 :     /*
                                 94                 :      * Update the pg_attribute entry for the column to show that a default
                                 95                 :      * exists.
                                 96                 :      */
                                 97            1717 :     attrrel = table_open(AttributeRelationId, RowExclusiveLock);
                                 98            1717 :     atttup = SearchSysCacheCopy2(ATTNUM,
                                 99                 :                                  ObjectIdGetDatum(RelationGetRelid(rel)),
                                100                 :                                  Int16GetDatum(attnum));
                                101            1717 :     if (!HeapTupleIsValid(atttup))
  384 tgl                       102 UBC           0 :         elog(ERROR, "cache lookup failed for attribute %d of relation %u",
                                103                 :              attnum, RelationGetRelid(rel));
  384 tgl                       104 CBC        1717 :     attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
                                105            1717 :     attgenerated = attStruct->attgenerated;
                                106            1717 :     if (!attStruct->atthasdef)
                                107                 :     {
                                108                 :         Form_pg_attribute defAttStruct;
                                109                 : 
                                110                 :         ExprState  *exprState;
                                111            1717 :         Expr       *expr2 = (Expr *) expr;
                                112            1717 :         EState     *estate = NULL;
                                113                 :         ExprContext *econtext;
  267 peter                     114 GNC        1717 :         Datum       valuesAtt[Natts_pg_attribute] = {0};
                                115            1717 :         bool        nullsAtt[Natts_pg_attribute] = {0};
                                116            1717 :         bool        replacesAtt[Natts_pg_attribute] = {0};
  384 tgl                       117 CBC        1717 :         Datum       missingval = (Datum) 0;
                                118            1717 :         bool        missingIsNull = true;
                                119                 : 
                                120            1717 :         valuesAtt[Anum_pg_attribute_atthasdef - 1] = true;
  384 tgl                       121 GIC        1717 :         replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
                                122                 : 
  384 tgl                       123 CBC        1717 :         if (rel->rd_rel->relkind == RELKIND_RELATION && add_column_mode &&
  384 tgl                       124 ECB             :             !attgenerated)
                                125                 :         {
  384 tgl                       126 CBC         220 :             expr2 = expression_planner(expr2);
  384 tgl                       127 GIC         220 :             estate = CreateExecutorState();
  384 tgl                       128 CBC         220 :             exprState = ExecPrepareExpr(expr2, estate);
  384 tgl                       129 GIC         220 :             econtext = GetPerTupleExprContext(estate);
                                130                 : 
  384 tgl                       131 CBC         220 :             missingval = ExecEvalExpr(exprState, econtext,
                                132                 :                                       &missingIsNull);
  384 tgl                       133 ECB             : 
  384 tgl                       134 GIC         220 :             FreeExecutorState(estate);
  384 tgl                       135 ECB             : 
  384 tgl                       136 GIC         220 :             defAttStruct = TupleDescAttr(rel->rd_att, attnum - 1);
                                137                 : 
  384 tgl                       138 GBC         220 :             if (missingIsNull)
                                139                 :             {
                                140                 :                 /* if the default evaluates to NULL, just store a NULL array */
  384 tgl                       141 UIC           0 :                 missingval = (Datum) 0;
                                142                 :             }
  384 tgl                       143 ECB             :             else
                                144                 :             {
                                145                 :                 /* otherwise make a one-element array of the value */
  384 tgl                       146 CBC         220 :                 missingval = PointerGetDatum(construct_array(&missingval,
  384 tgl                       147 ECB             :                                                              1,
                                148                 :                                                              defAttStruct->atttypid,
  384 tgl                       149 GIC         220 :                                                              defAttStruct->attlen,
                                150             220 :                                                              defAttStruct->attbyval,
  384 tgl                       151 CBC         220 :                                                              defAttStruct->attalign));
  384 tgl                       152 ECB             :             }
                                153                 : 
  384 tgl                       154 CBC         220 :             valuesAtt[Anum_pg_attribute_atthasmissing - 1] = !missingIsNull;
                                155             220 :             replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
  384 tgl                       156 GIC         220 :             valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval;
  384 tgl                       157 CBC         220 :             replacesAtt[Anum_pg_attribute_attmissingval - 1] = true;
  384 tgl                       158 GIC         220 :             nullsAtt[Anum_pg_attribute_attmissingval - 1] = missingIsNull;
                                159                 :         }
  384 tgl                       160 CBC        1717 :         atttup = heap_modify_tuple(atttup, RelationGetDescr(attrrel),
                                161                 :                                    valuesAtt, nullsAtt, replacesAtt);
  384 tgl                       162 ECB             : 
  384 tgl                       163 CBC        1717 :         CatalogTupleUpdate(attrrel, &atttup->t_self, atttup);
                                164                 : 
                                165            1717 :         if (!missingIsNull)
                                166             220 :             pfree(DatumGetPointer(missingval));
                                167                 :     }
  384 tgl                       168 GIC        1717 :     table_close(attrrel, RowExclusiveLock);
                                169            1717 :     heap_freetuple(atttup);
                                170                 : 
                                171                 :     /*
                                172                 :      * Make a dependency so that the pg_attrdef entry goes away if the column
                                173                 :      * (or whole table) is deleted.  In the case of a generated column, make
  384 tgl                       174 ECB             :      * it an internal dependency to prevent the default expression from being
                                175                 :      * deleted separately.
                                176                 :      */
  384 tgl                       177 GIC        1717 :     colobject.classId = RelationRelationId;
  384 tgl                       178 CBC        1717 :     colobject.objectId = RelationGetRelid(rel);
  384 tgl                       179 GIC        1717 :     colobject.objectSubId = attnum;
                                180                 : 
                                181            1717 :     recordDependencyOn(&defobject, &colobject,
                                182                 :                        attgenerated ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO);
                                183                 : 
  384 tgl                       184 ECB             :     /*
                                185                 :      * Record dependencies on objects used in the expression, too.
                                186                 :      */
  384 tgl                       187 GIC        1717 :     recordDependencyOnSingleRelExpr(&defobject, expr, RelationGetRelid(rel),
                                188                 :                                     DEPENDENCY_NORMAL,
                                189                 :                                     DEPENDENCY_NORMAL, false);
                                190                 : 
                                191                 :     /*
                                192                 :      * Post creation hook for attribute defaults.
                                193                 :      *
                                194                 :      * XXX. ALTER TABLE ALTER COLUMN SET/DROP DEFAULT is implemented with a
                                195                 :      * couple of deletion/creation of the attribute's default entry, so the
  384 tgl                       196 ECB             :      * callee should check existence of an older version of this entry if it
                                197                 :      * needs to distinguish.
                                198                 :      */
  384 tgl                       199 CBC        1717 :     InvokeObjectPostCreateHookArg(AttrDefaultRelationId,
                                200                 :                                   RelationGetRelid(rel), attnum, is_internal);
                                201                 : 
  384 tgl                       202 GIC        1717 :     return attrdefOid;
                                203                 : }
                                204                 : 
                                205                 : 
                                206                 : /*
                                207                 :  *      RemoveAttrDefault
                                208                 :  *
                                209                 :  * If the specified relation/attribute has a default, remove it.
  384 tgl                       210 ECB             :  * (If no default, raise error if complain is true, else return quietly.)
                                211                 :  */
                                212                 : void
  384 tgl                       213 GIC         308 : RemoveAttrDefault(Oid relid, AttrNumber attnum,
                                214                 :                   DropBehavior behavior, bool complain, bool internal)
                                215                 : {
                                216                 :     Relation    attrdef_rel;
  384 tgl                       217 ECB             :     ScanKeyData scankeys[2];
                                218                 :     SysScanDesc scan;
                                219                 :     HeapTuple   tuple;
  384 tgl                       220 GIC         308 :     bool        found = false;
  384 tgl                       221 ECB             : 
  384 tgl                       222 GIC         308 :     attrdef_rel = table_open(AttrDefaultRelationId, RowExclusiveLock);
                                223                 : 
                                224             308 :     ScanKeyInit(&scankeys[0],
  384 tgl                       225 ECB             :                 Anum_pg_attrdef_adrelid,
                                226                 :                 BTEqualStrategyNumber, F_OIDEQ,
                                227                 :                 ObjectIdGetDatum(relid));
  384 tgl                       228 GIC         308 :     ScanKeyInit(&scankeys[1],
                                229                 :                 Anum_pg_attrdef_adnum,
  384 tgl                       230 ECB             :                 BTEqualStrategyNumber, F_INT2EQ,
                                231                 :                 Int16GetDatum(attnum));
                                232                 : 
  384 tgl                       233 GIC         308 :     scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
  384 tgl                       234 ECB             :                               NULL, 2, scankeys);
                                235                 : 
                                236                 :     /* There should be at most one matching tuple, but we loop anyway */
  384 tgl                       237 CBC         505 :     while (HeapTupleIsValid(tuple = systable_getnext(scan)))
                                238                 :     {
  384 tgl                       239 ECB             :         ObjectAddress object;
  384 tgl                       240 CBC         197 :         Form_pg_attrdef attrtuple = (Form_pg_attrdef) GETSTRUCT(tuple);
  384 tgl                       241 ECB             : 
  384 tgl                       242 GIC         197 :         object.classId = AttrDefaultRelationId;
  384 tgl                       243 CBC         197 :         object.objectId = attrtuple->oid;
  384 tgl                       244 GIC         197 :         object.objectSubId = 0;
                                245                 : 
  384 tgl                       246 CBC         197 :         performDeletion(&object, behavior,
                                247                 :                         internal ? PERFORM_DELETION_INTERNAL : 0);
                                248                 : 
                                249             197 :         found = true;
  384 tgl                       250 ECB             :     }
                                251                 : 
  384 tgl                       252 CBC         308 :     systable_endscan(scan);
  384 tgl                       253 GBC         308 :     table_close(attrdef_rel, RowExclusiveLock);
                                254                 : 
  384 tgl                       255 CBC         308 :     if (complain && !found)
  384 tgl                       256 UIC           0 :         elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
                                257                 :              relid, attnum);
  384 tgl                       258 GIC         308 : }
                                259                 : 
                                260                 : /*
                                261                 :  *      RemoveAttrDefaultById
                                262                 :  *
                                263                 :  * Remove a pg_attrdef entry specified by OID.  This is the guts of
                                264                 :  * attribute-default removal.  Note it should be called via performDeletion,
  384 tgl                       265 ECB             :  * not directly.
                                266                 :  */
                                267                 : void
  384 tgl                       268 GIC        1296 : RemoveAttrDefaultById(Oid attrdefId)
                                269                 : {
                                270                 :     Relation    attrdef_rel;
                                271                 :     Relation    attr_rel;
                                272                 :     Relation    myrel;
                                273                 :     ScanKeyData scankeys[1];
                                274                 :     SysScanDesc scan;
                                275                 :     HeapTuple   tuple;
                                276                 :     Oid         myrelid;
  384 tgl                       277 ECB             :     AttrNumber  myattnum;
                                278                 : 
                                279                 :     /* Grab an appropriate lock on the pg_attrdef relation */
  384 tgl                       280 CBC        1296 :     attrdef_rel = table_open(AttrDefaultRelationId, RowExclusiveLock);
                                281                 : 
                                282                 :     /* Find the pg_attrdef tuple */
  384 tgl                       283 GIC        1296 :     ScanKeyInit(&scankeys[0],
                                284                 :                 Anum_pg_attrdef_oid,
  384 tgl                       285 ECB             :                 BTEqualStrategyNumber, F_OIDEQ,
                                286                 :                 ObjectIdGetDatum(attrdefId));
                                287                 : 
  384 tgl                       288 CBC        1296 :     scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true,
  384 tgl                       289 ECB             :                               NULL, 1, scankeys);
  384 tgl                       290 EUB             : 
  384 tgl                       291 GIC        1296 :     tuple = systable_getnext(scan);
  384 tgl                       292 CBC        1296 :     if (!HeapTupleIsValid(tuple))
  384 tgl                       293 LBC           0 :         elog(ERROR, "could not find tuple for attrdef %u", attrdefId);
                                294                 : 
  384 tgl                       295 GIC        1296 :     myrelid = ((Form_pg_attrdef) GETSTRUCT(tuple))->adrelid;
  384 tgl                       296 CBC        1296 :     myattnum = ((Form_pg_attrdef) GETSTRUCT(tuple))->adnum;
                                297                 : 
                                298                 :     /* Get an exclusive lock on the relation owning the attribute */
                                299            1296 :     myrel = relation_open(myrelid, AccessExclusiveLock);
                                300                 : 
  384 tgl                       301 ECB             :     /* Now we can delete the pg_attrdef row */
  384 tgl                       302 CBC        1296 :     CatalogTupleDelete(attrdef_rel, &tuple->t_self);
                                303                 : 
  384 tgl                       304 GIC        1296 :     systable_endscan(scan);
  384 tgl                       305 CBC        1296 :     table_close(attrdef_rel, RowExclusiveLock);
                                306                 : 
  384 tgl                       307 ECB             :     /* Fix the pg_attribute row */
  384 tgl                       308 GIC        1296 :     attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
                                309                 : 
  384 tgl                       310 CBC        1296 :     tuple = SearchSysCacheCopy2(ATTNUM,
  384 tgl                       311 EUB             :                                 ObjectIdGetDatum(myrelid),
                                312                 :                                 Int16GetDatum(myattnum));
  384 tgl                       313 GIC        1296 :     if (!HeapTupleIsValid(tuple))   /* shouldn't happen */
  384 tgl                       314 LBC           0 :         elog(ERROR, "cache lookup failed for attribute %d of relation %u",
                                315                 :              myattnum, myrelid);
  384 tgl                       316 ECB             : 
  384 tgl                       317 GIC        1296 :     ((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = false;
                                318                 : 
                                319            1296 :     CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
                                320                 : 
                                321                 :     /*
  384 tgl                       322 ECB             :      * Our update of the pg_attribute row will force a relcache rebuild, so
                                323                 :      * there's nothing else to do here.
                                324                 :      */
  384 tgl                       325 CBC        1296 :     table_close(attr_rel, RowExclusiveLock);
  384 tgl                       326 ECB             : 
                                327                 :     /* Keep lock on attribute's rel until end of xact */
  384 tgl                       328 GIC        1296 :     relation_close(myrel, NoLock);
                                329            1296 : }
                                330                 : 
                                331                 : 
                                332                 : /*
                                333                 :  * Get the pg_attrdef OID of the default expression for a column
                                334                 :  * identified by relation OID and column number.
                                335                 :  *
  384 tgl                       336 ECB             :  * Returns InvalidOid if there is no such pg_attrdef entry.
                                337                 :  */
                                338                 : Oid
  384 tgl                       339 GIC          19 : GetAttrDefaultOid(Oid relid, AttrNumber attnum)
                                340                 : {
                                341              19 :     Oid         result = InvalidOid;
                                342                 :     Relation    attrdef;
                                343                 :     ScanKeyData keys[2];
  384 tgl                       344 ECB             :     SysScanDesc scan;
                                345                 :     HeapTuple   tup;
                                346                 : 
  384 tgl                       347 GIC          19 :     attrdef = table_open(AttrDefaultRelationId, AccessShareLock);
                                348              19 :     ScanKeyInit(&keys[0],
                                349                 :                 Anum_pg_attrdef_adrelid,
  384 tgl                       350 ECB             :                 BTEqualStrategyNumber,
                                351                 :                 F_OIDEQ,
                                352                 :                 ObjectIdGetDatum(relid));
  384 tgl                       353 GIC          19 :     ScanKeyInit(&keys[1],
                                354                 :                 Anum_pg_attrdef_adnum,
  384 tgl                       355 ECB             :                 BTEqualStrategyNumber,
                                356                 :                 F_INT2EQ,
                                357                 :                 Int16GetDatum(attnum));
  384 tgl                       358 CBC          19 :     scan = systable_beginscan(attrdef, AttrDefaultIndexId, true,
                                359                 :                               NULL, 2, keys);
  384 tgl                       360 ECB             : 
  384 tgl                       361 GIC          19 :     if (HeapTupleIsValid(tup = systable_getnext(scan)))
  384 tgl                       362 ECB             :     {
  384 tgl                       363 GIC          19 :         Form_pg_attrdef atdform = (Form_pg_attrdef) GETSTRUCT(tup);
                                364                 : 
  384 tgl                       365 CBC          19 :         result = atdform->oid;
  384 tgl                       366 ECB             :     }
                                367                 : 
  384 tgl                       368 CBC          19 :     systable_endscan(scan);
  384 tgl                       369 GIC          19 :     table_close(attrdef, AccessShareLock);
                                370                 : 
                                371              19 :     return result;
                                372                 : }
                                373                 : 
                                374                 : /*
                                375                 :  * Given a pg_attrdef OID, return the relation OID and column number of
                                376                 :  * the owning column (represented as an ObjectAddress for convenience).
                                377                 :  *
  384 tgl                       378 ECB             :  * Returns InvalidObjectAddress if there is no such pg_attrdef entry.
                                379                 :  */
                                380                 : ObjectAddress
  384 tgl                       381 GIC        1284 : GetAttrDefaultColumnAddress(Oid attrdefoid)
                                382                 : {
                                383            1284 :     ObjectAddress result = InvalidObjectAddress;
                                384                 :     Relation    attrdef;
                                385                 :     ScanKeyData skey[1];
  384 tgl                       386 ECB             :     SysScanDesc scan;
                                387                 :     HeapTuple   tup;
                                388                 : 
  384 tgl                       389 GIC        1284 :     attrdef = table_open(AttrDefaultRelationId, AccessShareLock);
                                390            1284 :     ScanKeyInit(&skey[0],
  384 tgl                       391 ECB             :                 Anum_pg_attrdef_oid,
                                392                 :                 BTEqualStrategyNumber, F_OIDEQ,
                                393                 :                 ObjectIdGetDatum(attrdefoid));
  384 tgl                       394 CBC        1284 :     scan = systable_beginscan(attrdef, AttrDefaultOidIndexId, true,
                                395                 :                               NULL, 1, skey);
  384 tgl                       396 ECB             : 
  384 tgl                       397 GIC        1284 :     if (HeapTupleIsValid(tup = systable_getnext(scan)))
  384 tgl                       398 ECB             :     {
  384 tgl                       399 CBC        1275 :         Form_pg_attrdef atdform = (Form_pg_attrdef) GETSTRUCT(tup);
  384 tgl                       400 ECB             : 
  384 tgl                       401 GIC        1275 :         result.classId = RelationRelationId;
                                402            1275 :         result.objectId = atdform->adrelid;
  384 tgl                       403 CBC        1275 :         result.objectSubId = atdform->adnum;
  384 tgl                       404 ECB             :     }
                                405                 : 
  384 tgl                       406 CBC        1284 :     systable_endscan(scan);
  384 tgl                       407 GIC        1284 :     table_close(attrdef, AccessShareLock);
                                408                 : 
                                409            1284 :     return result;
                                410                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a