* 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
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
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;
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;
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))
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;
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;
}
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
HTAB *crosstab_hash;
HASHCTL ctl;
int ret;
- int proc;
+ uint64 proc;
MemoryContext SPIcontext;
/* initialize the category hash table */
{
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:
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);
char *rowid;
char *lastrowid = NULL;
bool firstpass = true;
- int i,
- j;
+ uint64 i;
+ int j;
int result_ncols;
if (num_categories == 0)
show_branch,
show_serial,
per_query_ctx,
- rsinfo->allowedModes & SFRM_Materialize_Random,
+ rsinfo->allowedModes & SFRM_Materialize_Random,
attinmeta);
rsinfo->setDesc = tupdesc;
show_branch,
show_serial,
per_query_ctx,
- rsinfo->allowedModes & SFRM_Materialize_Random,
+ rsinfo->allowedModes & SFRM_Materialize_Random,
attinmeta);
rsinfo->setDesc = tupdesc;
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,
{
TupleDesc tupdesc = attinmeta->tupdesc;
int ret;
- int proc;
+ uint64 proc;
int serial_column;
StringInfoData sql;
char **values;
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;
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 */
* 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;
/* 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 */
}
*/
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.")));
* 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 */
}
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.")));
* 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;