LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - tsquery_util.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 98.9 % 178 176 2 176
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 13 13 13
Baseline: 16@8cea358b128 Branches: 88.6 % 114 101 13 101
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 98.9 % 178 176 2 176
Function coverage date bins:
(240..) days: 100.0 % 13 13 13
Branch coverage date bins:
(240..) days: 88.6 % 114 101 13 101

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * tsquery_util.c
                                  4                 :                :  *    Utilities for tsquery datatype
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                  7                 :                :  *
                                  8                 :                :  *
                                  9                 :                :  * IDENTIFICATION
                                 10                 :                :  *    src/backend/utils/adt/tsquery_util.c
                                 11                 :                :  *
                                 12                 :                :  *-------------------------------------------------------------------------
                                 13                 :                :  */
                                 14                 :                : 
                                 15                 :                : #include "postgres.h"
                                 16                 :                : 
                                 17                 :                : #include "miscadmin.h"
                                 18                 :                : #include "tsearch/ts_utils.h"
                                 19                 :                : #include "varatt.h"
                                 20                 :                : 
                                 21                 :                : /*
                                 22                 :                :  * Build QTNode tree for a tsquery given in QueryItem array format.
                                 23                 :                :  */
                                 24                 :                : QTNode *
 5995 bruce@momjian.us           25                 :CBC        4419 : QT2QTN(QueryItem *in, char *operand)
                                 26                 :                : {
 6081 tgl@sss.pgh.pa.us          27                 :           4419 :     QTNode     *node = (QTNode *) palloc0(sizeof(QTNode));
                                 28                 :                : 
                                 29                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru           30                 :           4419 :     check_stack_depth();
                                 31                 :                : 
 6081 tgl@sss.pgh.pa.us          32                 :           4419 :     node->valnode = in;
                                 33                 :                : 
 6064 teodor@sigaev.ru           34         [ +  + ]:           4419 :     if (in->type == QI_OPR)
                                 35                 :                :     {
 6081 tgl@sss.pgh.pa.us          36                 :           1667 :         node->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
                                 37                 :           1667 :         node->child[0] = QT2QTN(in + 1, operand);
                                 38                 :           1667 :         node->sign = node->child[0]->sign;
 5386 peter_e@gmx.net            39         [ +  + ]:           1667 :         if (in->qoperator.oper == OP_NOT)
 6081 tgl@sss.pgh.pa.us          40                 :             21 :             node->nchild = 1;
                                 41                 :                :         else
                                 42                 :                :         {
                                 43                 :           1646 :             node->nchild = 2;
 5386 peter_e@gmx.net            44                 :           1646 :             node->child[1] = QT2QTN(in + in->qoperator.left, operand);
 6081 tgl@sss.pgh.pa.us          45                 :           1646 :             node->sign |= node->child[1]->sign;
                                 46                 :                :         }
                                 47                 :                :     }
                                 48         [ +  - ]:           2752 :     else if (operand)
                                 49                 :                :     {
 5386 peter_e@gmx.net            50                 :           2752 :         node->word = operand + in->qoperand.distance;
 5003 tgl@sss.pgh.pa.us          51                 :           2752 :         node->sign = ((uint32) 1) << (((unsigned int) in->qoperand.valcrc) % 32);
                                 52                 :                :     }
                                 53                 :                : 
 6081                            54                 :           4419 :     return node;
                                 55                 :                : }
                                 56                 :                : 
                                 57                 :                : /*
                                 58                 :                :  * Free a QTNode tree.
                                 59                 :                :  *
                                 60                 :                :  * Referenced "word" and "valnode" items are freed if marked as transient
                                 61                 :                :  * by flags.
                                 62                 :                :  */
                                 63                 :                : void
 5995 bruce@momjian.us           64                 :           4884 : QTNFree(QTNode *in)
                                 65                 :                : {
 6081 tgl@sss.pgh.pa.us          66         [ +  + ]:           4884 :     if (!in)
                                 67                 :              6 :         return;
                                 68                 :                : 
                                 69                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru           70                 :           4878 :     check_stack_depth();
                                 71                 :                : 
                                 72   [ +  +  +  -  :           4878 :     if (in->valnode->type == QI_VAL && in->word && (in->flags & QTN_WORDFREE) != 0)
                                              +  + ]
 6081 tgl@sss.pgh.pa.us          73                 :            306 :         pfree(in->word);
                                 74                 :                : 
 2723                            75         [ +  + ]:           4878 :     if (in->valnode->type == QI_OPR)
                                 76                 :                :     {
                                 77                 :                :         int         i;
                                 78                 :                : 
                                 79         [ +  + ]:           5493 :         for (i = 0; i < in->nchild; i++)
                                 80                 :           3673 :             QTNFree(in->child[i]);
                                 81                 :                :     }
                                 82         [ +  + ]:           4878 :     if (in->child)
                                 83                 :           1820 :         pfree(in->child);
                                 84                 :                : 
                                 85         [ +  + ]:           4878 :     if (in->flags & QTN_NEEDFREE)
                                 86                 :            576 :         pfree(in->valnode);
                                 87                 :                : 
 6081                            88                 :           4878 :     pfree(in);
                                 89                 :                : }
                                 90                 :                : 
                                 91                 :                : /*
                                 92                 :                :  * Sort comparator for QTNodes.
                                 93                 :                :  *
                                 94                 :                :  * The sort order is somewhat arbitrary.
                                 95                 :                :  */
                                 96                 :                : int
 5995 bruce@momjian.us           97                 :           1989 : QTNodeCompare(QTNode *an, QTNode *bn)
                                 98                 :                : {
                                 99                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru          100                 :           1989 :     check_stack_depth();
                                101                 :                : 
 6081 tgl@sss.pgh.pa.us         102         [ +  + ]:           1989 :     if (an->valnode->type != bn->valnode->type)
                                103         [ +  + ]:            591 :         return (an->valnode->type > bn->valnode->type) ? -1 : 1;
                                104                 :                : 
 6064 teodor@sigaev.ru          105         [ +  + ]:           1398 :     if (an->valnode->type == QI_OPR)
                                106                 :                :     {
 5386 peter_e@gmx.net           107                 :            271 :         QueryOperator *ao = &an->valnode->qoperator;
                                108                 :            271 :         QueryOperator *bo = &bn->valnode->qoperator;
                                109                 :                : 
 5995 bruce@momjian.us          110         [ +  + ]:            271 :         if (ao->oper != bo->oper)
 6064 teodor@sigaev.ru          111         [ +  + ]:             24 :             return (ao->oper > bo->oper) ? -1 : 1;
                                112                 :                : 
                                113         [ +  + ]:            247 :         if (an->nchild != bn->nchild)
                                114         [ +  - ]:             54 :             return (an->nchild > bn->nchild) ? -1 : 1;
                                115                 :                : 
                                116                 :                :         {
                                117                 :                :             int         i,
                                118                 :                :                         res;
                                119                 :                : 
                                120         [ +  + ]:            321 :             for (i = 0; i < an->nchild; i++)
                                121         [ +  + ]:            257 :                 if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0)
                                122                 :            129 :                     return res;
                                123                 :                :         }
                                124                 :                : 
 2929                           125   [ +  +  +  + ]:             64 :         if (ao->oper == OP_PHRASE && ao->distance != bo->distance)
                                126         [ +  - ]:              3 :             return (ao->distance > bo->distance) ? -1 : 1;
                                127                 :                : 
 6064                           128                 :             61 :         return 0;
                                129                 :                :     }
 5003 tgl@sss.pgh.pa.us         130         [ +  - ]:           1127 :     else if (an->valnode->type == QI_VAL)
                                131                 :                :     {
 5386 peter_e@gmx.net           132                 :           1127 :         QueryOperand *ao = &an->valnode->qoperand;
                                133                 :           1127 :         QueryOperand *bo = &bn->valnode->qoperand;
                                134                 :                : 
 6064 teodor@sigaev.ru          135         [ +  + ]:           1127 :         if (ao->valcrc != bo->valcrc)
                                136                 :                :         {
                                137         [ +  + ]:            876 :             return (ao->valcrc > bo->valcrc) ? -1 : 1;
                                138                 :                :         }
                                139                 :                : 
 5421 bruce@momjian.us          140                 :            251 :         return tsCompareString(an->word, ao->length, bn->word, bo->length, false);
                                141                 :                :     }
                                142                 :                :     else
                                143                 :                :     {
 5003 tgl@sss.pgh.pa.us         144         [ #  # ]:UBC           0 :         elog(ERROR, "unrecognized QueryItem type: %d", an->valnode->type);
                                145                 :                :         return 0;               /* keep compiler quiet */
                                146                 :                :     }
                                147                 :                : }
                                148                 :                : 
                                149                 :                : /*
                                150                 :                :  * qsort comparator for QTNode pointers.
                                151                 :                :  */
                                152                 :                : static int
 6081 tgl@sss.pgh.pa.us         153                 :CBC        1518 : cmpQTN(const void *a, const void *b)
                                154                 :                : {
 4326 bruce@momjian.us          155                 :           1518 :     return QTNodeCompare(*(QTNode *const *) a, *(QTNode *const *) b);
                                156                 :                : }
                                157                 :                : 
                                158                 :                : /*
                                159                 :                :  * Canonicalize a QTNode tree by sorting the children of AND/OR nodes
                                160                 :                :  * into an arbitrary but well-defined order.
                                161                 :                :  */
                                162                 :                : void
 5995                           163                 :           4542 : QTNSort(QTNode *in)
                                164                 :                : {
                                165                 :                :     int         i;
                                166                 :                : 
                                167                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru          168                 :           4542 :     check_stack_depth();
                                169                 :                : 
                                170         [ +  + ]:           4542 :     if (in->valnode->type != QI_OPR)
 6081 tgl@sss.pgh.pa.us         171                 :           2958 :         return;
                                172                 :                : 
                                173         [ +  + ]:           5199 :     for (i = 0; i < in->nchild; i++)
                                174                 :           3615 :         QTNSort(in->child[i]);
 2929 teodor@sigaev.ru          175   [ +  +  +  + ]:           1584 :     if (in->nchild > 1 && in->valnode->qoperator.oper != OP_PHRASE)
  432 peter@eisentraut.org      176                 :            924 :         qsort(in->child, in->nchild, sizeof(QTNode *), cmpQTN);
                                177                 :                : }
                                178                 :                : 
                                179                 :                : /*
                                180                 :                :  * Are two QTNode trees equal according to QTNodeCompare?
                                181                 :                :  */
                                182                 :                : bool
 5995 bruce@momjian.us          183                 :             99 : QTNEq(QTNode *a, QTNode *b)
                                184                 :                : {
 6081 tgl@sss.pgh.pa.us         185                 :             99 :     uint32      sign = a->sign & b->sign;
                                186                 :                : 
                                187   [ +  +  -  + ]:             99 :     if (!(sign == a->sign && sign == b->sign))
 2723                           188                 :              3 :         return false;
                                189                 :                : 
  949 michael@paquier.xyz       190                 :             96 :     return (QTNodeCompare(a, b) == 0);
                                191                 :                : }
                                192                 :                : 
                                193                 :                : /*
                                194                 :                :  * Remove unnecessary intermediate nodes. For example:
                                195                 :                :  *
                                196                 :                :  *  OR          OR
                                197                 :                :  * a  OR    -> a b c
                                198                 :                :  *   b  c
                                199                 :                :  */
                                200                 :                : void
 5995 bruce@momjian.us          201                 :           4374 : QTNTernary(QTNode *in)
                                202                 :                : {
                                203                 :                :     int         i;
                                204                 :                : 
                                205                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru          206                 :           4374 :     check_stack_depth();
                                207                 :                : 
                                208         [ +  + ]:           4374 :     if (in->valnode->type != QI_OPR)
 6081 tgl@sss.pgh.pa.us         209                 :           2769 :         return;
                                210                 :                : 
                                211         [ +  + ]:           5073 :     for (i = 0; i < in->nchild; i++)
                                212                 :           3468 :         QTNTernary(in->child[i]);
                                213                 :                : 
                                214                 :                :     /* Only AND and OR are associative, so don't flatten other node types */
 2723                           215         [ +  + ]:           1605 :     if (in->valnode->qoperator.oper != OP_AND &&
                                216         [ +  + ]:           1008 :         in->valnode->qoperator.oper != OP_OR)
                                217                 :            624 :         return;
                                218                 :                : 
 6081                           219         [ +  + ]:           3213 :     for (i = 0; i < in->nchild; i++)
                                220                 :                :     {
 6064 teodor@sigaev.ru          221                 :           2232 :         QTNode     *cc = in->child[i];
                                222                 :                : 
 2929                           223         [ +  + ]:           2232 :         if (cc->valnode->type == QI_OPR &&
 2723 tgl@sss.pgh.pa.us         224         [ +  + ]:            777 :             in->valnode->qoperator.oper == cc->valnode->qoperator.oper)
                                225                 :                :         {
 6081                           226                 :            165 :             int         oldnchild = in->nchild;
                                227                 :                : 
                                228                 :            165 :             in->nchild += cc->nchild - 1;
                                229                 :            165 :             in->child = (QTNode **) repalloc(in->child, in->nchild * sizeof(QTNode *));
                                230                 :                : 
                                231         [ +  + ]:            165 :             if (i + 1 != oldnchild)
                                232                 :             18 :                 memmove(in->child + i + cc->nchild, in->child + i + 1,
                                233                 :             18 :                         (oldnchild - i - 1) * sizeof(QTNode *));
                                234                 :                : 
                                235                 :            165 :             memcpy(in->child + i, cc->child, cc->nchild * sizeof(QTNode *));
                                236                 :            165 :             i += cc->nchild - 1;
                                237                 :                : 
 5995 bruce@momjian.us          238         [ +  + ]:            165 :             if (cc->flags & QTN_NEEDFREE)
 6064 teodor@sigaev.ru          239                 :             54 :                 pfree(cc->valnode);
 6081 tgl@sss.pgh.pa.us         240                 :            165 :             pfree(cc);
                                241                 :                :         }
                                242                 :                :     }
                                243                 :                : }
                                244                 :                : 
                                245                 :                : /*
                                246                 :                :  * Convert a tree to binary tree by inserting intermediate nodes.
                                247                 :                :  * (Opposite of QTNTernary)
                                248                 :                :  */
                                249                 :                : void
 5995 bruce@momjian.us          250                 :            591 : QTNBinary(QTNode *in)
                                251                 :                : {
                                252                 :                :     int         i;
                                253                 :                : 
                                254                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru          255                 :            591 :     check_stack_depth();
                                256                 :                : 
                                257         [ +  + ]:            591 :     if (in->valnode->type != QI_OPR)
 6081 tgl@sss.pgh.pa.us         258                 :            363 :         return;
                                259                 :                : 
                                260         [ +  + ]:            732 :     for (i = 0; i < in->nchild; i++)
                                261                 :            504 :         QTNBinary(in->child[i]);
                                262                 :                : 
                                263         [ +  + ]:            288 :     while (in->nchild > 2)
                                264                 :                :     {
                                265                 :             60 :         QTNode     *nn = (QTNode *) palloc0(sizeof(QTNode));
                                266                 :                : 
                                267                 :             60 :         nn->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
                                268                 :             60 :         nn->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
                                269                 :                : 
                                270                 :             60 :         nn->nchild = 2;
                                271                 :             60 :         nn->flags = QTN_NEEDFREE;
                                272                 :                : 
                                273                 :             60 :         nn->child[0] = in->child[0];
                                274                 :             60 :         nn->child[1] = in->child[1];
                                275                 :             60 :         nn->sign = nn->child[0]->sign | nn->child[1]->sign;
                                276                 :                : 
                                277                 :             60 :         nn->valnode->type = in->valnode->type;
 5386 peter_e@gmx.net           278                 :             60 :         nn->valnode->qoperator.oper = in->valnode->qoperator.oper;
                                279                 :                : 
 6081 tgl@sss.pgh.pa.us         280                 :             60 :         in->child[0] = nn;
                                281                 :             60 :         in->child[1] = in->child[in->nchild - 1];
                                282                 :             60 :         in->nchild--;
                                283                 :                :     }
                                284                 :                : }
                                285                 :                : 
                                286                 :                : /*
                                287                 :                :  * Count the total length of operand strings in tree (including '\0'-
                                288                 :                :  * terminators) and the total number of nodes.
                                289                 :                :  * Caller must initialize *sumlen and *nnode to zeroes.
                                290                 :                :  */
                                291                 :                : static void
 5995 bruce@momjian.us          292                 :            993 : cntsize(QTNode *in, int *sumlen, int *nnode)
                                293                 :                : {
                                294                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru          295                 :            993 :     check_stack_depth();
                                296                 :                : 
 6081 tgl@sss.pgh.pa.us         297                 :            993 :     *nnode += 1;
 6064 teodor@sigaev.ru          298         [ +  + ]:            993 :     if (in->valnode->type == QI_OPR)
                                299                 :                :     {
                                300                 :                :         int         i;
                                301                 :                : 
 6081 tgl@sss.pgh.pa.us         302         [ +  + ]:           1281 :         for (i = 0; i < in->nchild; i++)
                                303                 :            846 :             cntsize(in->child[i], sumlen, nnode);
                                304                 :                :     }
                                305                 :                :     else
                                306                 :                :     {
 5386 peter_e@gmx.net           307                 :            558 :         *sumlen += in->valnode->qoperand.length + 1;
                                308                 :                :     }
 6081 tgl@sss.pgh.pa.us         309                 :            993 : }
                                310                 :                : 
                                311                 :                : typedef struct
                                312                 :                : {
                                313                 :                :     QueryItem  *curitem;
                                314                 :                :     char       *operand;
                                315                 :                :     char       *curoperand;
                                316                 :                : } QTN2QTState;
                                317                 :                : 
                                318                 :                : /*
                                319                 :                :  * Recursively convert a QTNode tree into flat tsquery format.
                                320                 :                :  * Caller must have allocated arrays of the correct size.
                                321                 :                :  */
                                322                 :                : static void
 5995 bruce@momjian.us          323                 :            993 : fillQT(QTN2QTState *state, QTNode *in)
                                324                 :                : {
                                325                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru          326                 :            993 :     check_stack_depth();
                                327                 :                : 
                                328         [ +  + ]:            993 :     if (in->valnode->type == QI_VAL)
                                329                 :                :     {
                                330                 :            558 :         memcpy(state->curitem, in->valnode, sizeof(QueryOperand));
                                331                 :                : 
 5386 peter_e@gmx.net           332                 :            558 :         memcpy(state->curoperand, in->word, in->valnode->qoperand.length);
                                333                 :            558 :         state->curitem->qoperand.distance = state->curoperand - state->operand;
                                334                 :            558 :         state->curoperand[in->valnode->qoperand.length] = '\0';
                                335                 :            558 :         state->curoperand += in->valnode->qoperand.length + 1;
 6081 tgl@sss.pgh.pa.us         336                 :            558 :         state->curitem++;
                                337                 :                :     }
                                338                 :                :     else
                                339                 :                :     {
                                340                 :            435 :         QueryItem  *curitem = state->curitem;
                                341                 :                : 
 6064 teodor@sigaev.ru          342         [ -  + ]:            435 :         Assert(in->valnode->type == QI_OPR);
                                343                 :                : 
                                344                 :            435 :         memcpy(state->curitem, in->valnode, sizeof(QueryOperator));
                                345                 :                : 
 6081 tgl@sss.pgh.pa.us         346         [ -  + ]:            435 :         Assert(in->nchild <= 2);
                                347                 :            435 :         state->curitem++;
                                348                 :                : 
                                349                 :            435 :         fillQT(state, in->child[0]);
                                350                 :                : 
                                351         [ +  + ]:            435 :         if (in->nchild == 2)
                                352                 :                :         {
 5386 peter_e@gmx.net           353                 :            411 :             curitem->qoperator.left = state->curitem - curitem;
 6081 tgl@sss.pgh.pa.us         354                 :            411 :             fillQT(state, in->child[1]);
                                355                 :                :         }
                                356                 :                :     }
                                357                 :            993 : }
                                358                 :                : 
                                359                 :                : /*
                                360                 :                :  * Build flat tsquery from a QTNode tree.
                                361                 :                :  */
                                362                 :                : TSQuery
 5995 bruce@momjian.us          363                 :            147 : QTN2QT(QTNode *in)
                                364                 :                : {
                                365                 :                :     TSQuery     out;
                                366                 :                :     int         len;
 6081 tgl@sss.pgh.pa.us         367                 :            147 :     int         sumlen = 0,
                                368                 :            147 :                 nnode = 0;
                                369                 :                :     QTN2QTState state;
                                370                 :                : 
                                371                 :            147 :     cntsize(in, &sumlen, &nnode);
                                372                 :                : 
 3709 noah@leadboat.com         373         [ -  + ]:            147 :     if (TSQUERY_TOO_BIG(nnode, sumlen))
 3709 noah@leadboat.com         374         [ #  # ]:UBC           0 :         ereport(ERROR,
                                375                 :                :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                376                 :                :                  errmsg("tsquery is too large")));
 6081 tgl@sss.pgh.pa.us         377                 :CBC         147 :     len = COMPUTESIZE(nnode, sumlen);
                                378                 :                : 
 4709                           379                 :            147 :     out = (TSQuery) palloc0(len);
 6081                           380                 :            147 :     SET_VARSIZE(out, len);
                                381                 :            147 :     out->size = nnode;
                                382                 :                : 
                                383                 :            147 :     state.curitem = GETQUERY(out);
                                384                 :            147 :     state.operand = state.curoperand = GETOPERAND(out);
                                385                 :                : 
                                386                 :            147 :     fillQT(&state, in);
                                387                 :            147 :     return out;
                                388                 :                : }
                                389                 :                : 
                                390                 :                : /*
                                391                 :                :  * Copy a QTNode tree.
                                392                 :                :  *
                                393                 :                :  * Modifiable copies of the words and valnodes are made, too.
                                394                 :                :  */
                                395                 :                : QTNode *
 5995 bruce@momjian.us          396                 :            510 : QTNCopy(QTNode *in)
                                397                 :                : {
                                398                 :                :     QTNode     *out;
                                399                 :                : 
                                400                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6064 teodor@sigaev.ru          401                 :            510 :     check_stack_depth();
                                402                 :                : 
                                403                 :            510 :     out = (QTNode *) palloc(sizeof(QTNode));
                                404                 :                : 
 6081 tgl@sss.pgh.pa.us         405                 :            510 :     *out = *in;
                                406                 :            510 :     out->valnode = (QueryItem *) palloc(sizeof(QueryItem));
                                407                 :            510 :     *(out->valnode) = *(in->valnode);
                                408                 :            510 :     out->flags |= QTN_NEEDFREE;
                                409                 :                : 
 6064 teodor@sigaev.ru          410         [ +  + ]:            510 :     if (in->valnode->type == QI_VAL)
                                411                 :                :     {
 5386 peter_e@gmx.net           412                 :            306 :         out->word = palloc(in->valnode->qoperand.length + 1);
                                413                 :            306 :         memcpy(out->word, in->word, in->valnode->qoperand.length);
                                414                 :            306 :         out->word[in->valnode->qoperand.length] = '\0';
 6081 tgl@sss.pgh.pa.us         415                 :            306 :         out->flags |= QTN_WORDFREE;
                                416                 :                :     }
                                417                 :                :     else
                                418                 :                :     {
                                419                 :                :         int         i;
                                420                 :                : 
                                421                 :            204 :         out->child = (QTNode **) palloc(sizeof(QTNode *) * in->nchild);
                                422                 :                : 
                                423         [ +  + ]:            609 :         for (i = 0; i < in->nchild; i++)
                                424                 :            405 :             out->child[i] = QTNCopy(in->child[i]);
                                425                 :                :     }
                                426                 :                : 
                                427                 :            510 :     return out;
                                428                 :                : }
                                429                 :                : 
                                430                 :                : /*
                                431                 :                :  * Clear the specified flag bit(s) in all nodes of a QTNode tree.
                                432                 :                :  */
                                433                 :                : void
 5995 bruce@momjian.us          434                 :           2622 : QTNClearFlags(QTNode *in, uint32 flags)
                                435                 :                : {
                                436                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 6018 tgl@sss.pgh.pa.us         437                 :           2622 :     check_stack_depth();
                                438                 :                : 
                                439                 :           2622 :     in->flags &= ~flags;
                                440                 :                : 
                                441         [ +  + ]:           2622 :     if (in->valnode->type != QI_VAL)
                                442                 :                :     {
                                443                 :                :         int         i;
                                444                 :                : 
                                445         [ +  + ]:           3204 :         for (i = 0; i < in->nchild; i++)
                                446                 :           2226 :             QTNClearFlags(in->child[i], flags);
                                447                 :                :     }
                                448                 :           2622 : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622