*** ./src/backend/executor/nodeLimit.c.orig Sun Jun 25 15:02:46 2006 --- ./src/backend/executor/nodeLimit.c Mon Jun 26 14:31:04 2006 *************** *** 23,29 **** #include "executor/executor.h" #include "executor/nodeLimit.h" ! static void recompute_limits(LimitState *node); --- 23,29 ---- #include "executor/executor.h" #include "executor/nodeLimit.h" ! #include "catalog/pg_type.h" static void recompute_limits(LimitState *node); *************** *** 226,239 **** { ExprContext *econtext = node->ps.ps_ExprContext; bool isNull; if (node->limitOffset) { ! node->offset = ! DatumGetInt32(ExecEvalExprSwitchContext(node->limitOffset, econtext, &isNull, NULL)); /* Interpret NULL offset as no offset */ if (isNull) node->offset = 0; --- 226,250 ---- { ExprContext *econtext = node->ps.ps_ExprContext; bool isNull; + Oid type; if (node->limitOffset) { ! type = ((Const *) node->limitOffset->expr)->consttype; ! ! if(type == INT8OID) ! node->offset = ! DatumGetInt64(ExecEvalExprSwitchContext(node->limitOffset, econtext, &isNull, NULL)); + else + node->offset = + DatumGetInt32(ExecEvalExprSwitchContext(node->limitOffset, + econtext, + &isNull, + NULL)); + /* Interpret NULL offset as no offset */ if (isNull) node->offset = 0; *************** *** 249,259 **** if (node->limitCount) { node->noCount = false; ! node->count = ! DatumGetInt32(ExecEvalExprSwitchContext(node->limitCount, econtext, &isNull, NULL)); /* Interpret NULL count as no count (LIMIT ALL) */ if (isNull) node->noCount = true; --- 260,280 ---- if (node->limitCount) { node->noCount = false; ! type = ((Const *) node->limitCount->expr)->consttype; ! ! if(type == INT8OID) ! node->count = ! DatumGetInt64(ExecEvalExprSwitchContext(node->limitCount, econtext, &isNull, NULL)); + else + node->count = + DatumGetInt32(ExecEvalExprSwitchContext(node->limitCount, + econtext, + &isNull, + NULL)); + /* Interpret NULL count as no count (LIMIT ALL) */ if (isNull) node->noCount = true; *** ./src/backend/parser/parse_clause.c.orig Sun Jun 25 14:55:42 2006 --- ./src/backend/parser/parse_clause.c Mon Jun 26 14:50:28 2006 *************** *** 1092,1098 **** qual = transformExpr(pstate, clause); ! qual = coerce_to_integer(pstate, qual, constructName); /* * LIMIT can't refer to any vars or aggregates of the current query; we --- 1092,1098 ---- qual = transformExpr(pstate, clause); ! qual = coerce_to_integer8(pstate, qual, constructName); /* * LIMIT can't refer to any vars or aggregates of the current query; we *** ./src/backend/parser/parse_coerce.c.orig Sun Jun 25 15:07:28 2006 --- ./src/backend/parser/parse_coerce.c Mon Jun 26 14:38:36 2006 *************** *** 822,828 **** /* coerce_to_integer() * Coerce an argument of a construct that requires integer input ! * (LIMIT, OFFSET, etc). Also check that input is not a set. * * Returns the possibly-transformed node tree. * --- 822,828 ---- /* coerce_to_integer() * Coerce an argument of a construct that requires integer input ! * Also check that input is not a set. * * Returns the possibly-transformed node tree. * *************** *** 859,865 **** --- 859,903 ---- return node; } + /* coerce_to_integer8() + * Coerce an argument of a construct that requires integer input + * (LIMIT, OFFSET). Also check that input is not a set. + * + * Returns the possibly-transformed node tree. + * + * As with coerce_type, pstate may be NULL if no special unknown-Param + * processing is wanted. + */ + Node * + coerce_to_integer8(ParseState *pstate, Node *node, + const char *constructName) + { + Oid inputTypeId = exprType(node); + if (inputTypeId != INT8OID) + { + node = coerce_to_target_type(pstate, node, inputTypeId, + INT8OID, -1, + COERCION_ASSIGNMENT, + COERCE_IMPLICIT_CAST); + if (node == NULL) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + /* translator: first %s is name of a SQL construct, eg LIMIT */ + errmsg("argument of %s must be type integer, not type %s", + constructName, format_type_be(inputTypeId)))); + } + + if (expression_returns_set(node)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + /* translator: %s is name of a SQL construct, eg LIMIT */ + errmsg("argument of %s must not return a set", + constructName))); + + return node; + } + /* select_common_type() * Determine the common supertype of a list of input expression types. * This is used for determining the output type of CASE and UNION *** ./src/include/parser/parse_coerce.h.orig Sun Jun 25 15:00:21 2006 --- ./src/include/parser/parse_coerce.h Sun Jun 25 15:00:58 2006 *************** *** 58,64 **** const char *constructName); extern Node *coerce_to_integer(ParseState *pstate, Node *node, const char *constructName); ! extern Oid select_common_type(List *typeids, const char *context); extern Node *coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, --- 58,65 ---- const char *constructName); extern Node *coerce_to_integer(ParseState *pstate, Node *node, const char *constructName); ! extern Node *coerce_to_integer8(ParseState *pstate, Node *node, ! const char *constructName); extern Oid select_common_type(List *typeids, const char *context); extern Node *coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId,