]> granicus.if.org Git - postgresql/blobdiff - contrib/tablefunc/tablefunc.c
Update copyright for 2018
[postgresql] / contrib / tablefunc / tablefunc.c
index 8a95d4710b700d7650ef404bed6df882f9c47f79..59f90dc947943716fb6cadc0b0a2445802379ac3 100644 (file)
@@ -10,7 +10,7 @@
  * And contributors:
  * Nabil Sayegh <postgresql@e-trolley.de>
  *
- * Copyright (c) 2002-2015, PostgreSQL Global Development Group
+ * Copyright (c) 2002-2018, PostgreSQL Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and its
  * documentation for any purpose, without fee, and without a written agreement
@@ -120,7 +120,7 @@ typedef struct
 typedef struct crosstab_cat_desc
 {
        char       *catname;            /* full category name */
-       int                     attidx;                 /* zero based */
+       uint64          attidx;                 /* zero based */
 } crosstab_cat_desc;
 
 #define MAX_CATNAME_LEN                        NAMEDATALEN
@@ -174,8 +174,8 @@ Datum
 normal_rand(PG_FUNCTION_ARGS)
 {
        FuncCallContext *funcctx;
-       int                     call_cntr;
-       int                     max_calls;
+       uint64          call_cntr;
+       uint64          max_calls;
        normal_rand_fctx *fctx;
        float8          mean;
        float8          stddev;
@@ -352,8 +352,8 @@ crosstab(PG_FUNCTION_ARGS)
        ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
        Tuplestorestate *tupstore;
        TupleDesc       tupdesc;
-       int                     call_cntr;
-       int                     max_calls;
+       uint64          call_cntr;
+       uint64          max_calls;
        AttInMetadata *attinmeta;
        SPITupleTable *spi_tuptable;
        TupleDesc       spi_tupdesc;
@@ -364,7 +364,7 @@ crosstab(PG_FUNCTION_ARGS)
        MemoryContext per_query_ctx;
        MemoryContext oldcontext;
        int                     ret;
-       int                     proc;
+       uint64          proc;
 
        /* check to see if caller supports us returning a tuplestore */
        if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
@@ -389,7 +389,7 @@ crosstab(PG_FUNCTION_ARGS)
        proc = SPI_processed;
 
        /* If no qualifying tuples, fall out early */
-       if (ret != SPI_OK_SELECT || proc <= 0)
+       if (ret != SPI_OK_SELECT || proc == 0)
        {
                SPI_finish();
                rsinfo->isDone = ExprEndResult;
@@ -432,7 +432,9 @@ crosstab(PG_FUNCTION_ARGS)
                        break;
                default:
                        /* result type isn't composite */
-                       elog(ERROR, "return type must be a row type");
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
+                                        errmsg("return type must be a row type")));
                        break;
        }
 
@@ -682,7 +684,7 @@ crosstab_hash(PG_FUNCTION_ARGS)
                                                                                                crosstab_hash,
                                                                                                tupdesc,
                                                                                                per_query_ctx,
-                                                        rsinfo->allowedModes & SFRM_Materialize_Random);
+                                                                                               rsinfo->allowedModes & SFRM_Materialize_Random);
 
        /*
         * SFRM_Materialize mode expects us to return a NULL Datum. The actual
@@ -706,7 +708,7 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
        HTAB       *crosstab_hash;
        HASHCTL         ctl;
        int                     ret;
-       int                     proc;
+       uint64          proc;
        MemoryContext SPIcontext;
 
        /* initialize the category hash table */
@@ -738,7 +740,7 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
        {
                SPITupleTable *spi_tuptable = SPI_tuptable;
                TupleDesc       spi_tupdesc = spi_tuptable->tupdesc;
-               int                     i;
+               uint64          i;
 
                /*
                 * The provided categories SQL query must always return one column:
@@ -798,7 +800,7 @@ get_crosstab_tuplestore(char *sql,
        char      **values;
        HeapTuple       tuple;
        int                     ret;
-       int                     proc;
+       uint64          proc;
 
        /* initialize our tuplestore (while still in query context!) */
        tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
@@ -821,8 +823,8 @@ get_crosstab_tuplestore(char *sql,
                char       *rowid;
                char       *lastrowid = NULL;
                bool            firstpass = true;
-               int                     i,
-                                       j;
+               uint64          i;
+               int                     j;
                int                     result_ncols;
 
                if (num_categories == 0)
@@ -1044,7 +1046,7 @@ connectby_text(PG_FUNCTION_ARGS)
                                                                  show_branch,
                                                                  show_serial,
                                                                  per_query_ctx,
-                                                         rsinfo->allowedModes & SFRM_Materialize_Random,
+                                                                 rsinfo->allowedModes & SFRM_Materialize_Random,
                                                                  attinmeta);
        rsinfo->setDesc = tupdesc;
 
@@ -1124,7 +1126,7 @@ connectby_text_serial(PG_FUNCTION_ARGS)
                                                                  show_branch,
                                                                  show_serial,
                                                                  per_query_ctx,
-                                                         rsinfo->allowedModes & SFRM_Materialize_Random,
+                                                                 rsinfo->allowedModes & SFRM_Materialize_Random,
                                                                  attinmeta);
        rsinfo->setDesc = tupdesc;
 
@@ -1185,8 +1187,8 @@ connectby(char *relname,
                                                                 branch_delim,
                                                                 start_with,
                                                                 start_with,    /* current_branch */
-                                                                0,             /* initial level is 0 */
-                                                                &serial,               /* initial serial is 1 */
+                                                                0, /* initial level is 0 */
+                                                                &serial,       /* initial serial is 1 */
                                                                 max_depth,
                                                                 show_branch,
                                                                 show_serial,
@@ -1218,7 +1220,7 @@ build_tuplestore_recursively(char *key_fld,
 {
        TupleDesc       tupdesc = attinmeta->tupdesc;
        int                     ret;
-       int                     proc;
+       uint64          proc;
        int                     serial_column;
        StringInfoData sql;
        char      **values;
@@ -1311,7 +1313,7 @@ build_tuplestore_recursively(char *key_fld,
                HeapTuple       spi_tuple;
                SPITupleTable *tuptable = SPI_tuptable;
                TupleDesc       spi_tupdesc = tuptable->tupdesc;
-               int                     i;
+               uint64          i;
                StringInfoData branchstr;
                StringInfoData chk_branchstr;
                StringInfoData chk_current_key;
@@ -1350,7 +1352,9 @@ build_tuplestore_recursively(char *key_fld,
                                appendStringInfo(&chk_current_key, "%s%s%s",
                                                                 branch_delim, current_key, branch_delim);
                                if (strstr(chk_branchstr.data, chk_current_key.data))
-                                       elog(ERROR, "infinite recursion detected");
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_INVALID_RECURSION),
+                                                        errmsg("infinite recursion detected")));
                        }
 
                        /* OK, extend the branch */
@@ -1417,7 +1421,7 @@ build_tuplestore_recursively(char *key_fld,
  * Check expected (query runtime) tupdesc suitable for Connectby
  */
 static void
-validateConnectbyTupleDesc(TupleDesc tupdesc, bool show_branch, bool show_serial)
+validateConnectbyTupleDesc(TupleDesc td, bool show_branch, bool show_serial)
 {
        int                     serial_column = 0;
 
@@ -1427,55 +1431,63 @@ validateConnectbyTupleDesc(TupleDesc tupdesc, bool show_branch, bool show_serial
        /* are there the correct number of columns */
        if (show_branch)
        {
-               if (tupdesc->natts != (CONNECTBY_NCOLS + serial_column))
+               if (td->natts != (CONNECTBY_NCOLS + serial_column))
                        ereport(ERROR,
-                                       (errcode(ERRCODE_SYNTAX_ERROR),
+                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
                                         errmsg("invalid return type"),
                                         errdetail("Query-specified return tuple has " \
                                                           "wrong number of columns.")));
        }
        else
        {
-               if (tupdesc->natts != CONNECTBY_NCOLS_NOBRANCH + serial_column)
+               if (td->natts != CONNECTBY_NCOLS_NOBRANCH + serial_column)
                        ereport(ERROR,
-                                       (errcode(ERRCODE_SYNTAX_ERROR),
+                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
                                         errmsg("invalid return type"),
                                         errdetail("Query-specified return tuple has " \
                                                           "wrong number of columns.")));
        }
 
        /* check that the types of the first two columns match */
-       if (tupdesc->attrs[0]->atttypid != tupdesc->attrs[1]->atttypid)
+       if (TupleDescAttr(td, 0)->atttypid != TupleDescAttr(td, 1)->atttypid)
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
                                 errmsg("invalid return type"),
                                 errdetail("First two columns must be the same type.")));
 
        /* check that the type of the third column is INT4 */
-       if (tupdesc->attrs[2]->atttypid != INT4OID)
+       if (TupleDescAttr(td, 2)->atttypid != INT4OID)
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
                                 errmsg("invalid return type"),
                                 errdetail("Third column must be type %s.",
                                                   format_type_be(INT4OID))));
 
        /* check that the type of the fourth column is TEXT if applicable */
-       if (show_branch && tupdesc->attrs[3]->atttypid != TEXTOID)
+       if (show_branch && TupleDescAttr(td, 3)->atttypid != TEXTOID)
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
                                 errmsg("invalid return type"),
                                 errdetail("Fourth column must be type %s.",
                                                   format_type_be(TEXTOID))));
 
        /* check that the type of the fifth column is INT4 */
-       if (show_branch && show_serial && tupdesc->attrs[4]->atttypid != INT4OID)
-               elog(ERROR, "query-specified return tuple not valid for Connectby: "
-                        "fifth column must be type %s", format_type_be(INT4OID));
+       if (show_branch && show_serial &&
+               TupleDescAttr(td, 4)->atttypid != INT4OID)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
+                                errmsg("query-specified return tuple not valid for Connectby: "
+                                               "fifth column must be type %s",
+                                               format_type_be(INT4OID))));
 
        /* check that the type of the fifth column is INT4 */
-       if (!show_branch && show_serial && tupdesc->attrs[3]->atttypid != INT4OID)
-               elog(ERROR, "query-specified return tuple not valid for Connectby: "
-                        "fourth column must be type %s", format_type_be(INT4OID));
+       if (!show_branch && show_serial &&
+               TupleDescAttr(td, 3)->atttypid != INT4OID)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
+                                errmsg("query-specified return tuple not valid for Connectby: "
+                                               "fourth column must be type %s",
+                                               format_type_be(INT4OID))));
 
        /* OK, the tupdesc is valid for our purposes */
 }
@@ -1496,7 +1508,7 @@ compatConnectbyTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
         */
        if (sql_tupdesc->natts < 2)
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
                                 errmsg("invalid return type"),
                                 errdetail("Query must return at least two columns.")));
 
@@ -1504,33 +1516,33 @@ compatConnectbyTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
         * These columns must match the result type indicated by the calling
         * query.
         */
-       ret_atttypid = ret_tupdesc->attrs[0]->atttypid;
-       sql_atttypid = sql_tupdesc->attrs[0]->atttypid;
-       ret_atttypmod = ret_tupdesc->attrs[0]->atttypmod;
-       sql_atttypmod = sql_tupdesc->attrs[0]->atttypmod;
+       ret_atttypid = TupleDescAttr(ret_tupdesc, 0)->atttypid;
+       sql_atttypid = TupleDescAttr(sql_tupdesc, 0)->atttypid;
+       ret_atttypmod = TupleDescAttr(ret_tupdesc, 0)->atttypmod;
+       sql_atttypmod = TupleDescAttr(sql_tupdesc, 0)->atttypmod;
        if (ret_atttypid != sql_atttypid ||
                (ret_atttypmod >= 0 && ret_atttypmod != sql_atttypmod))
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
                                 errmsg("invalid return type"),
                                 errdetail("SQL key field type %s does " \
                                                   "not match return key field type %s.",
-                                          format_type_with_typemod(ret_atttypid, ret_atttypmod),
-                                       format_type_with_typemod(sql_atttypid, sql_atttypmod))));
+                                                  format_type_with_typemod(ret_atttypid, ret_atttypmod),
+                                                  format_type_with_typemod(sql_atttypid, sql_atttypmod))));
 
-       ret_atttypid = ret_tupdesc->attrs[1]->atttypid;
-       sql_atttypid = sql_tupdesc->attrs[1]->atttypid;
-       ret_atttypmod = ret_tupdesc->attrs[1]->atttypmod;
-       sql_atttypmod = sql_tupdesc->attrs[1]->atttypmod;
+       ret_atttypid = TupleDescAttr(ret_tupdesc, 1)->atttypid;
+       sql_atttypid = TupleDescAttr(sql_tupdesc, 1)->atttypid;
+       ret_atttypmod = TupleDescAttr(ret_tupdesc, 1)->atttypmod;
+       sql_atttypmod = TupleDescAttr(sql_tupdesc, 1)->atttypmod;
        if (ret_atttypid != sql_atttypid ||
                (ret_atttypmod >= 0 && ret_atttypmod != sql_atttypmod))
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
                                 errmsg("invalid return type"),
                                 errdetail("SQL parent key field type %s does " \
                                                   "not match return parent key field type %s.",
-                                          format_type_with_typemod(ret_atttypid, ret_atttypmod),
-                                       format_type_with_typemod(sql_atttypid, sql_atttypmod))));
+                                                  format_type_with_typemod(ret_atttypid, ret_atttypmod),
+                                                  format_type_with_typemod(sql_atttypid, sql_atttypmod))));
 
        /* OK, the two tupdescs are compatible for our purposes */
 }
@@ -1552,11 +1564,11 @@ compatCrosstabTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
                return false;
 
        /* check the rowid types match */
-       ret_atttypid = ret_tupdesc->attrs[0]->atttypid;
-       sql_atttypid = sql_tupdesc->attrs[0]->atttypid;
+       ret_atttypid = TupleDescAttr(ret_tupdesc, 0)->atttypid;
+       sql_atttypid = TupleDescAttr(sql_tupdesc, 0)->atttypid;
        if (ret_atttypid != sql_atttypid)
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_DATATYPE_MISMATCH),
                                 errmsg("invalid return type"),
                                 errdetail("SQL rowid datatype does not match " \
                                                   "return rowid datatype.")));
@@ -1566,10 +1578,10 @@ compatCrosstabTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
         * attribute [2] of the sql tuple should match attributes [1] to [natts]
         * of the return tuple
         */
-       sql_attr = sql_tupdesc->attrs[2];
+       sql_attr = TupleDescAttr(sql_tupdesc, 2);
        for (i = 1; i < ret_tupdesc->natts; i++)
        {
-               ret_attr = ret_tupdesc->attrs[i];
+               ret_attr = TupleDescAttr(ret_tupdesc, i);
 
                if (ret_attr->atttypid != sql_attr->atttypid)
                        return false;