~ubuntu-branches/ubuntu/trusty/postgresql-9.3/trusty-proposed

« back to all changes in this revision

Viewing changes to src/backend/utils/adt/ruleutils.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2016-03-31 11:04:53 UTC
  • mfrom: (1.1.11) (18.1.4 trusty-security)
  • Revision ID: package-import@ubuntu.com-20160331110453-h6xfs9f11suj3mze
Tags: 9.3.12-0ubuntu0.14.04
* New upstream bug fix release. (LP: #1564268)
  - See http://www.postgresql.org/about/news/1656/ for details.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include "commands/tablespace.h"
37
37
#include "executor/spi.h"
38
38
#include "funcapi.h"
 
39
#include "mb/pg_wchar.h"
39
40
#include "miscadmin.h"
40
41
#include "nodes/makefuncs.h"
41
42
#include "nodes/nodeFuncs.h"
52
53
#include "utils/array.h"
53
54
#include "utils/builtins.h"
54
55
#include "utils/fmgroids.h"
 
56
#include "utils/hsearch.h"
55
57
#include "utils/lsyscache.h"
56
58
#include "utils/rel.h"
57
59
#include "utils/syscache.h"
260
262
#define deparse_columns_fetch(rangetable_index, dpns) \
261
263
        ((deparse_columns *) list_nth((dpns)->rtable_columns, (rangetable_index)-1))
262
264
 
 
265
/*
 
266
 * Entry in set_rtable_names' hash table
 
267
 */
 
268
typedef struct
 
269
{
 
270
        char            name[NAMEDATALEN];              /* Hash key --- must be first */
 
271
        int                     counter;                /* Largest addition used so far for name */
 
272
} NameHashEntry;
 
273
 
263
274
 
264
275
/* ----------
265
276
 * Global data
304
315
static void print_function_rettype(StringInfo buf, HeapTuple proctup);
305
316
static void set_rtable_names(deparse_namespace *dpns, List *parent_namespaces,
306
317
                                 Bitmapset *rels_used);
307
 
static bool refname_is_unique(char *refname, deparse_namespace *dpns,
308
 
                                  List *parent_namespaces);
309
318
static void set_deparse_for_query(deparse_namespace *dpns, Query *query,
310
319
                                          List *parent_namespaces);
311
320
static void set_simple_column_names(deparse_namespace *dpns);
378
387
static void removeStringInfoSpaces(StringInfo str);
379
388
static void get_rule_expr(Node *node, deparse_context *context,
380
389
                          bool showimplicit);
 
390
static void get_rule_expr_toplevel(Node *node, deparse_context *context,
 
391
                                           bool showimplicit);
381
392
static void get_oper_expr(OpExpr *expr, deparse_context *context);
382
393
static void get_func_expr(FuncExpr *expr, deparse_context *context,
383
394
                          bool showimplicit);
407
418
static void printSubscripts(ArrayRef *aref, deparse_context *context);
408
419
static char *get_relation_name(Oid relid);
409
420
static char *generate_relation_name(Oid relid, List *namespaces);
 
421
static char *generate_qualified_relation_name(Oid relid);
410
422
static char *generate_function_name(Oid funcid, int nargs,
411
423
                                           List *argnames, Oid *argtypes,
412
424
                                           bool was_variadic, bool *use_variadic_p);
1285
1297
                                                                                                                          prettyFlags)));
1286
1298
}
1287
1299
 
1288
 
/* Internal version that returns a palloc'd C string; no pretty-printing */
 
1300
/*
 
1301
 * Internal version that returns a full ALTER TABLE ... ADD CONSTRAINT command
 
1302
 */
1289
1303
char *
1290
1304
pg_get_constraintdef_string(Oid constraintId)
1291
1305
{
1307
1321
 
1308
1322
        initStringInfo(&buf);
1309
1323
 
1310
 
        if (fullCommand && OidIsValid(conForm->conrelid))
 
1324
        if (fullCommand)
1311
1325
        {
1312
 
                appendStringInfo(&buf, "ALTER TABLE ONLY %s ADD CONSTRAINT %s ",
1313
 
                                                 generate_relation_name(conForm->conrelid, NIL),
 
1326
                /*
 
1327
                 * Currently, callers want ALTER TABLE (without ONLY) for CHECK
 
1328
                 * constraints, and other types of constraints don't inherit anyway so
 
1329
                 * it doesn't matter whether we say ONLY or not.  Someday we might
 
1330
                 * need to let callers specify whether to put ONLY in the command.
 
1331
                 */
 
1332
                appendStringInfo(&buf, "ALTER TABLE %s ADD CONSTRAINT %s ",
 
1333
                                                 generate_qualified_relation_name(conForm->conrelid),
1314
1334
                                                 quote_identifier(NameStr(conForm->conname)));
1315
1335
        }
1316
1336
 
1833
1853
 
1834
1854
        if (OidIsValid(sequenceId))
1835
1855
        {
1836
 
                HeapTuple       classtup;
1837
 
                Form_pg_class classtuple;
1838
 
                char       *nspname;
1839
1856
                char       *result;
1840
1857
 
1841
 
                /* Get the sequence's pg_class entry */
1842
 
                classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(sequenceId));
1843
 
                if (!HeapTupleIsValid(classtup))
1844
 
                        elog(ERROR, "cache lookup failed for relation %u", sequenceId);
1845
 
                classtuple = (Form_pg_class) GETSTRUCT(classtup);
1846
 
 
1847
 
                /* Get the namespace */
1848
 
                nspname = get_namespace_name(classtuple->relnamespace);
1849
 
                if (!nspname)
1850
 
                        elog(ERROR, "cache lookup failed for namespace %u",
1851
 
                                 classtuple->relnamespace);
1852
 
 
1853
 
                /* And construct the result string */
1854
 
                result = quote_qualified_identifier(nspname,
1855
 
                                                                                        NameStr(classtuple->relname));
1856
 
 
1857
 
                ReleaseSysCache(classtup);
 
1858
                result = generate_qualified_relation_name(sequenceId);
1858
1859
 
1859
1860
                PG_RETURN_TEXT_P(string_to_text(result));
1860
1861
        }
2489
2490
set_rtable_names(deparse_namespace *dpns, List *parent_namespaces,
2490
2491
                                 Bitmapset *rels_used)
2491
2492
{
 
2493
        HASHCTL         hash_ctl;
 
2494
        HTAB       *names_hash;
 
2495
        NameHashEntry *hentry;
 
2496
        bool            found;
 
2497
        int                     rtindex;
2492
2498
        ListCell   *lc;
2493
 
        int                     rtindex = 1;
2494
2499
 
2495
2500
        dpns->rtable_names = NIL;
 
2501
        /* nothing more to do if empty rtable */
 
2502
        if (dpns->rtable == NIL)
 
2503
                return;
 
2504
 
 
2505
        /*
 
2506
         * We use a hash table to hold known names, so that this process is O(N)
 
2507
         * not O(N^2) for N names.
 
2508
         */
 
2509
        MemSet(&hash_ctl, 0, sizeof(hash_ctl));
 
2510
        hash_ctl.keysize = NAMEDATALEN;
 
2511
        hash_ctl.entrysize = sizeof(NameHashEntry);
 
2512
        hash_ctl.hcxt = CurrentMemoryContext;
 
2513
        names_hash = hash_create("set_rtable_names names",
 
2514
                                                         list_length(dpns->rtable),
 
2515
                                                         &hash_ctl,
 
2516
                                                         HASH_ELEM | HASH_CONTEXT);
 
2517
        /* Preload the hash table with names appearing in parent_namespaces */
 
2518
        foreach(lc, parent_namespaces)
 
2519
        {
 
2520
                deparse_namespace *olddpns = (deparse_namespace *) lfirst(lc);
 
2521
                ListCell   *lc2;
 
2522
 
 
2523
                foreach(lc2, olddpns->rtable_names)
 
2524
                {
 
2525
                        char       *oldname = (char *) lfirst(lc2);
 
2526
 
 
2527
                        if (oldname == NULL)
 
2528
                                continue;
 
2529
                        hentry = (NameHashEntry *) hash_search(names_hash,
 
2530
                                                                                                   oldname,
 
2531
                                                                                                   HASH_ENTER,
 
2532
                                                                                                   &found);
 
2533
                        /* we do not complain about duplicate names in parent namespaces */
 
2534
                        hentry->counter = 0;
 
2535
                }
 
2536
        }
 
2537
 
 
2538
        /* Now we can scan the rtable */
 
2539
        rtindex = 1;
2496
2540
        foreach(lc, dpns->rtable)
2497
2541
        {
2498
2542
                RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
2499
2543
                char       *refname;
2500
2544
 
 
2545
                /* Just in case this takes an unreasonable amount of time ... */
 
2546
                CHECK_FOR_INTERRUPTS();
 
2547
 
2501
2548
                if (rels_used && !bms_is_member(rtindex, rels_used))
2502
2549
                {
2503
2550
                        /* Ignore unreferenced RTE */
2525
2572
                }
2526
2573
 
2527
2574
                /*
2528
 
                 * If the selected name isn't unique, append digits to make it so
 
2575
                 * If the selected name isn't unique, append digits to make it so, and
 
2576
                 * make a new hash entry for it once we've got a unique name.  For a
 
2577
                 * very long input name, we might have to truncate to stay within
 
2578
                 * NAMEDATALEN.
2529
2579
                 */
2530
 
                if (refname &&
2531
 
                        !refname_is_unique(refname, dpns, parent_namespaces))
 
2580
                if (refname)
2532
2581
                {
2533
 
                        char       *modname = (char *) palloc(strlen(refname) + 32);
2534
 
                        int                     i = 0;
 
2582
                        hentry = (NameHashEntry *) hash_search(names_hash,
 
2583
                                                                                                   refname,
 
2584
                                                                                                   HASH_ENTER,
 
2585
                                                                                                   &found);
 
2586
                        if (found)
 
2587
                        {
 
2588
                                /* Name already in use, must choose a new one */
 
2589
                                int                     refnamelen = strlen(refname);
 
2590
                                char       *modname = (char *) palloc(refnamelen + 16);
 
2591
                                NameHashEntry *hentry2;
2535
2592
 
2536
 
                        do
 
2593
                                do
 
2594
                                {
 
2595
                                        hentry->counter++;
 
2596
                                        for (;;)
 
2597
                                        {
 
2598
                                                /*
 
2599
                                                 * We avoid using %.*s here because it can misbehave
 
2600
                                                 * if the data is not valid in what libc thinks is the
 
2601
                                                 * prevailing encoding.
 
2602
                                                 */
 
2603
                                                memcpy(modname, refname, refnamelen);
 
2604
                                                sprintf(modname + refnamelen, "_%d", hentry->counter);
 
2605
                                                if (strlen(modname) < NAMEDATALEN)
 
2606
                                                        break;
 
2607
                                                /* drop chars from refname to keep all the digits */
 
2608
                                                refnamelen = pg_mbcliplen(refname, refnamelen,
 
2609
                                                                                                  refnamelen - 1);
 
2610
                                        }
 
2611
                                        hentry2 = (NameHashEntry *) hash_search(names_hash,
 
2612
                                                                                                                        modname,
 
2613
                                                                                                                        HASH_ENTER,
 
2614
                                                                                                                        &found);
 
2615
                                } while (found);
 
2616
                                hentry2->counter = 0;   /* init new hash entry */
 
2617
                                refname = modname;
 
2618
                        }
 
2619
                        else
2537
2620
                        {
2538
 
                                sprintf(modname, "%s_%d", refname, ++i);
2539
 
                        } while (!refname_is_unique(modname, dpns, parent_namespaces));
2540
 
                        refname = modname;
 
2621
                                /* Name not previously used, need only initialize hentry */
 
2622
                                hentry->counter = 0;
 
2623
                        }
2541
2624
                }
2542
2625
 
2543
2626
                dpns->rtable_names = lappend(dpns->rtable_names, refname);
2544
2627
                rtindex++;
2545
2628
        }
2546
 
}
2547
 
 
2548
 
/*
2549
 
 * refname_is_unique: is refname distinct from all already-chosen RTE names?
2550
 
 */
2551
 
static bool
2552
 
refname_is_unique(char *refname, deparse_namespace *dpns,
2553
 
                                  List *parent_namespaces)
2554
 
{
2555
 
        ListCell   *lc;
2556
 
 
2557
 
        foreach(lc, dpns->rtable_names)
2558
 
        {
2559
 
                char       *oldname = (char *) lfirst(lc);
2560
 
 
2561
 
                if (oldname && strcmp(oldname, refname) == 0)
2562
 
                        return false;
2563
 
        }
2564
 
        foreach(lc, parent_namespaces)
2565
 
        {
2566
 
                deparse_namespace *olddpns = (deparse_namespace *) lfirst(lc);
2567
 
                ListCell   *lc2;
2568
 
 
2569
 
                foreach(lc2, olddpns->rtable_names)
2570
 
                {
2571
 
                        char       *oldname = (char *) lfirst(lc2);
2572
 
 
2573
 
                        if (oldname && strcmp(oldname, refname) == 0)
2574
 
                                return false;
2575
 
                }
2576
 
        }
2577
 
        return true;
 
2629
 
 
2630
        hash_destroy(names_hash);
2578
2631
}
2579
2632
 
2580
2633
/*
3402
3455
                                        deparse_columns *colinfo)
3403
3456
{
3404
3457
        /*
3405
 
         * If the selected name isn't unique, append digits to make it so
 
3458
         * If the selected name isn't unique, append digits to make it so.  For a
 
3459
         * very long input name, we might have to truncate to stay within
 
3460
         * NAMEDATALEN.
3406
3461
         */
3407
3462
        if (!colname_is_unique(colname, dpns, colinfo))
3408
3463
        {
3409
 
                char       *modname = (char *) palloc(strlen(colname) + 32);
 
3464
                int                     colnamelen = strlen(colname);
 
3465
                char       *modname = (char *) palloc(colnamelen + 16);
3410
3466
                int                     i = 0;
3411
3467
 
3412
3468
                do
3413
3469
                {
3414
 
                        sprintf(modname, "%s_%d", colname, ++i);
 
3470
                        i++;
 
3471
                        for (;;)
 
3472
                        {
 
3473
                                /*
 
3474
                                 * We avoid using %.*s here because it can misbehave if the
 
3475
                                 * data is not valid in what libc thinks is the prevailing
 
3476
                                 * encoding.
 
3477
                                 */
 
3478
                                memcpy(modname, colname, colnamelen);
 
3479
                                sprintf(modname + colnamelen, "_%d", i);
 
3480
                                if (strlen(modname) < NAMEDATALEN)
 
3481
                                        break;
 
3482
                                /* drop chars from colname to keep all the digits */
 
3483
                                colnamelen = pg_mbcliplen(colname, colnamelen,
 
3484
                                                                                  colnamelen - 1);
 
3485
                        }
3415
3486
                } while (!colname_is_unique(modname, dpns, colinfo));
3416
3487
                colname = modname;
3417
3488
        }
4162
4233
 
4163
4234
                        /*
4164
4235
                         * Strip any top-level nodes representing indirection assignments,
4165
 
                         * then print the result.
 
4236
                         * then print the result.  Whole-row Vars need special treatment.
4166
4237
                         */
4167
 
                        get_rule_expr(processIndirection(col, context, false),
4168
 
                                                  context, false);
 
4238
                        get_rule_expr_toplevel(processIndirection(col, context, false),
 
4239
                                                                   context, false);
4169
4240
                }
4170
4241
                appendStringInfoChar(buf, ')');
4171
4242
        }
4556
4627
                 * the top level of a SELECT list it's not right (the parser will
4557
4628
                 * expand that notation into multiple columns, yielding behavior
4558
4629
                 * different from a whole-row Var).  We need to call get_variable
4559
 
                 * directly so that we can tell it to do the right thing.
 
4630
                 * directly so that we can tell it to do the right thing, and so that
 
4631
                 * we can get the attribute name which is the default AS label.
4560
4632
                 */
4561
4633
                if (tle->expr && IsA(tle->expr, Var))
4562
4634
                {
7045
7117
                                                !tupdesc->attrs[i]->attisdropped)
7046
7118
                                        {
7047
7119
                                                appendStringInfoString(buf, sep);
7048
 
                                                get_rule_expr(e, context, true);
 
7120
                                                /* Whole-row Vars need special treatment here */
 
7121
                                                get_rule_expr_toplevel(e, context, true);
7049
7122
                                                sep = ", ";
7050
7123
                                        }
7051
7124
                                        i++;
7425
7498
        }
7426
7499
}
7427
7500
 
 
7501
/*
 
7502
 * get_rule_expr_toplevel               - Parse back a toplevel expression
 
7503
 *
 
7504
 * Same as get_rule_expr(), except that if the expr is just a Var, we pass
 
7505
 * istoplevel = true not false to get_variable().  This causes whole-row Vars
 
7506
 * to get printed with decoration that will prevent expansion of "*".
 
7507
 * We need to use this in contexts such as ROW() and VALUES(), where the
 
7508
 * parser would expand "foo.*" appearing at top level.  (In principle we'd
 
7509
 * use this in get_target_list() too, but that has additional worries about
 
7510
 * whether to print AS, so it needs to invoke get_variable() directly anyway.)
 
7511
 */
 
7512
static void
 
7513
get_rule_expr_toplevel(Node *node, deparse_context *context,
 
7514
                                           bool showimplicit)
 
7515
{
 
7516
        if (node && IsA(node, Var))
 
7517
                (void) get_variable((Var *) node, 0, true, context);
 
7518
        else
 
7519
                get_rule_expr(node, context, showimplicit);
 
7520
}
 
7521
 
7428
7522
 
7429
7523
/*
7430
7524
 * get_oper_expr                        - Parse back an OpExpr node
8759
8853
}
8760
8854
 
8761
8855
/*
 
8856
 * generate_qualified_relation_name
 
8857
 *              Compute the name to display for a relation specified by OID
 
8858
 *
 
8859
 * As above, but unconditionally schema-qualify the name.
 
8860
 */
 
8861
static char *
 
8862
generate_qualified_relation_name(Oid relid)
 
8863
{
 
8864
        HeapTuple       tp;
 
8865
        Form_pg_class reltup;
 
8866
        char       *relname;
 
8867
        char       *nspname;
 
8868
        char       *result;
 
8869
 
 
8870
        tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
 
8871
        if (!HeapTupleIsValid(tp))
 
8872
                elog(ERROR, "cache lookup failed for relation %u", relid);
 
8873
        reltup = (Form_pg_class) GETSTRUCT(tp);
 
8874
        relname = NameStr(reltup->relname);
 
8875
 
 
8876
        nspname = get_namespace_name(reltup->relnamespace);
 
8877
        if (!nspname)
 
8878
                elog(ERROR, "cache lookup failed for namespace %u",
 
8879
                         reltup->relnamespace);
 
8880
 
 
8881
        result = quote_qualified_identifier(nspname, relname);
 
8882
 
 
8883
        ReleaseSysCache(tp);
 
8884
 
 
8885
        return result;
 
8886
}
 
8887
 
 
8888
/*
8762
8889
 * generate_function_name
8763
8890
 *              Compute the name to display for a function specified by OID,
8764
8891
 *              given that it is being called with the specified actual arg names and
8998
9125
                                                                 Anum_pg_class_reloptions, &isnull);
8999
9126
        if (!isnull)
9000
9127
        {
9001
 
                Datum           sep,
9002
 
                                        txt;
9003
 
 
9004
 
                /*
9005
 
                 * We want to use array_to_text(reloptions, ', ') --- but
9006
 
                 * DirectFunctionCall2(array_to_text) does not work, because
9007
 
                 * array_to_text() relies on flinfo to be valid.  So use
9008
 
                 * OidFunctionCall2.
9009
 
                 */
9010
 
                sep = CStringGetTextDatum(", ");
9011
 
                txt = OidFunctionCall2(F_ARRAY_TO_TEXT, reloptions, sep);
9012
 
                result = TextDatumGetCString(txt);
 
9128
                StringInfoData buf;
 
9129
                Datum      *options;
 
9130
                int                     noptions;
 
9131
                int                     i;
 
9132
 
 
9133
                initStringInfo(&buf);
 
9134
 
 
9135
                deconstruct_array(DatumGetArrayTypeP(reloptions),
 
9136
                                                  TEXTOID, -1, false, 'i',
 
9137
                                                  &options, NULL, &noptions);
 
9138
 
 
9139
                for (i = 0; i < noptions; i++)
 
9140
                {
 
9141
                        char       *option = TextDatumGetCString(options[i]);
 
9142
                        char       *name;
 
9143
                        char       *separator;
 
9144
                        char       *value;
 
9145
 
 
9146
                        /*
 
9147
                         * Each array element should have the form name=value.  If the "="
 
9148
                         * is missing for some reason, treat it like an empty value.
 
9149
                         */
 
9150
                        name = option;
 
9151
                        separator = strchr(option, '=');
 
9152
                        if (separator)
 
9153
                        {
 
9154
                                *separator = '\0';
 
9155
                                value = separator + 1;
 
9156
                        }
 
9157
                        else
 
9158
                                value = "";
 
9159
 
 
9160
                        if (i > 0)
 
9161
                                appendStringInfoString(&buf, ", ");
 
9162
                        appendStringInfo(&buf, "%s=", quote_identifier(name));
 
9163
 
 
9164
                        /*
 
9165
                         * In general we need to quote the value; but to avoid unnecessary
 
9166
                         * clutter, do not quote if it is an identifier that would not
 
9167
                         * need quoting.  (We could also allow numbers, but that is a bit
 
9168
                         * trickier than it looks --- for example, are leading zeroes
 
9169
                         * significant?  We don't want to assume very much here about what
 
9170
                         * custom reloptions might mean.)
 
9171
                         */
 
9172
                        if (quote_identifier(value) == value)
 
9173
                                appendStringInfoString(&buf, value);
 
9174
                        else
 
9175
                                simple_quote_literal(&buf, value);
 
9176
 
 
9177
                        pfree(option);
 
9178
                }
 
9179
 
 
9180
                result = buf.data;
9013
9181
        }
9014
9182
 
9015
9183
        ReleaseSysCache(tuple);