* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.92 2003/09/28 23:37:45 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.93 2003/10/01 21:47:42 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
-#include "utils/syscache.h"
static const char *const raise_skip_msg = "RAISE";
static int exec_eval_integer(PLpgSQL_execstate * estate,
PLpgSQL_expr * expr,
bool *isNull);
+static bool exec_eval_boolean(PLpgSQL_execstate * estate,
+ PLpgSQL_expr * expr,
+ bool *isNull);
static Datum exec_eval_expr(PLpgSQL_execstate * estate,
PLpgSQL_expr * expr,
bool *isNull,
static HeapTuple make_tuple_from_row(PLpgSQL_execstate * estate,
PLpgSQL_row * row,
TupleDesc tupdesc);
+static char *convert_value_to_string(Datum value, Oid valtype);
static Datum exec_cast_value(Datum value, Oid valtype,
Oid reqtype,
FmgrInfo *reqinput,
static int
exec_stmt_if(PLpgSQL_execstate * estate, PLpgSQL_stmt_if * stmt)
{
- Datum value;
- Oid valtype;
+ bool value;
bool isnull = false;
- value = exec_eval_expr(estate, stmt->cond, &isnull, &valtype);
+ value = exec_eval_boolean(estate, stmt->cond, &isnull);
exec_eval_cleanup(estate);
- if (!isnull && DatumGetBool(value))
+ if (!isnull && value)
{
if (stmt->true_body != NULL)
return exec_stmts(estate, stmt->true_body);
static int
exec_stmt_while(PLpgSQL_execstate * estate, PLpgSQL_stmt_while * stmt)
{
- Datum value;
- Oid valtype;
+ bool value;
bool isnull = false;
int rc;
for (;;)
{
- value = exec_eval_expr(estate, stmt->cond, &isnull, &valtype);
+ value = exec_eval_boolean(estate, stmt->cond, &isnull);
exec_eval_cleanup(estate);
- if (isnull || !DatumGetBool(value))
+
+ if (isnull || !value)
break;
rc = exec_stmts(estate, stmt->body);
static int
exec_stmt_exit(PLpgSQL_execstate * estate, PLpgSQL_stmt_exit * stmt)
{
- Datum value;
- Oid valtype;
- bool isnull = false;
-
/*
* If the exit has a condition, check that it's true
*/
if (stmt->cond != NULL)
{
- value = exec_eval_expr(estate, stmt->cond, &isnull, &valtype);
+ bool value;
+ bool isnull = false;
+
+ value = exec_eval_boolean(estate, stmt->cond, &isnull);
exec_eval_cleanup(estate);
- if (isnull || !DatumGetBool(value))
+ if (isnull || !value)
return PLPGSQL_RC_OK;
}
Oid paramtypeid;
Datum paramvalue;
bool paramisnull;
- HeapTuple typetup;
- Form_pg_type typeStruct;
- FmgrInfo finfo_output;
char *extval;
int pidx = 0;
char c[2] = {0, 0};
if (paramisnull)
extval = "<NULL>";
else
- {
- typetup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(paramtypeid),
- 0, 0, 0);
- if (!HeapTupleIsValid(typetup))
- elog(ERROR, "cache lookup failed for type %u",
- paramtypeid);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
-
- fmgr_info(typeStruct->typoutput, &finfo_output);
- extval = DatumGetCString(FunctionCall3(&finfo_output,
- paramvalue,
- ObjectIdGetDatum(typeStruct->typelem),
- Int32GetDatum(-1)));
- ReleaseSysCache(typetup);
- }
+ extval = convert_value_to_string(paramvalue, paramtypeid);
plpgsql_dstring_append(&ds, extval);
pidx++;
continue;
bool isnull = false;
Oid restype;
char *querystr;
- HeapTuple typetup;
- Form_pg_type typeStruct;
- FmgrInfo finfo_output;
int exec_res;
/*
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("cannot EXECUTE a null querystring")));
- /*
- * Get the C-String representation.
- */
- typetup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(restype),
- 0, 0, 0);
- if (!HeapTupleIsValid(typetup))
- elog(ERROR, "cache lookup failed for type %u", restype);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
+ /* Get the C-String representation */
+ querystr = convert_value_to_string(query, restype);
- fmgr_info(typeStruct->typoutput, &finfo_output);
- querystr = DatumGetCString(FunctionCall3(&finfo_output,
- query,
- ObjectIdGetDatum(typeStruct->typelem),
- Int32GetDatum(-1)));
-
- ReleaseSysCache(typetup);
exec_eval_cleanup(estate);
/*
int rc = PLPGSQL_RC_OK;
int i;
int n;
- HeapTuple typetup;
- Form_pg_type typeStruct;
- FmgrInfo finfo_output;
void *plan;
Portal portal;
bool found = false;
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("cannot EXECUTE a null querystring")));
- /*
- * Get the C-String representation.
- */
- typetup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(restype),
- 0, 0, 0);
- if (!HeapTupleIsValid(typetup))
- elog(ERROR, "cache lookup failed for type %u", restype);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
-
- fmgr_info(typeStruct->typoutput, &finfo_output);
- querystr = DatumGetCString(FunctionCall3(&finfo_output,
- query,
- ObjectIdGetDatum(typeStruct->typelem),
- Int32GetDatum(-1)));
+ /* Get the C-String representation */
+ querystr = convert_value_to_string(query, restype);
- ReleaseSysCache(typetup);
exec_eval_cleanup(estate);
/*
Datum queryD;
Oid restype;
char *querystr;
- HeapTuple typetup;
- Form_pg_type typeStruct;
- FmgrInfo finfo_output;
void *curplan;
/* ----------
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("cannot EXECUTE a null querystring")));
- /* ----------
- * Get the C-String representation.
- * ----------
- */
- typetup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(restype),
- 0, 0, 0);
- if (!HeapTupleIsValid(typetup))
- elog(ERROR, "cache lookup failed for type %u", restype);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
-
- fmgr_info(typeStruct->typoutput, &finfo_output);
- querystr = DatumGetCString(FunctionCall3(&finfo_output,
- queryD,
- ObjectIdGetDatum(typeStruct->typelem),
- Int32GetDatum(-1)));
-
- ReleaseSysCache(typetup);
+ /* Get the C-String representation */
+ querystr = convert_value_to_string(queryD, restype);
+
exec_eval_cleanup(estate);
/* ----------
return DatumGetInt32(exprdatum);
}
+/* ----------
+ * exec_eval_boolean Evaluate an expression, coerce result to bool
+ *
+ * Note we do not do exec_eval_cleanup here; the caller must do it at
+ * some later point.
+ * ----------
+ */
+static bool
+exec_eval_boolean(PLpgSQL_execstate * estate,
+ PLpgSQL_expr * expr,
+ bool *isNull)
+{
+ Datum exprdatum;
+ Oid exprtypeid;
+
+ exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid);
+ exprdatum = exec_simple_cast_value(exprdatum, exprtypeid,
+ BOOLOID, -1,
+ isNull);
+ return DatumGetBool(exprdatum);
+}
+
/* ----------
* exec_eval_expr Evaluate an expression and return
* the result Datum.
return tuple;
}
+/* ----------
+ * convert_value_to_string Convert a non-null Datum to C string
+ *
+ * Note: callers generally assume that the result is a palloc'd string and
+ * should be pfree'd. This is not all that safe an assumption ...
+ * ----------
+ */
+static char *
+convert_value_to_string(Datum value, Oid valtype)
+{
+ Oid typOutput;
+ Oid typElem;
+ bool typIsVarlena;
+ FmgrInfo finfo_output;
+
+ getTypeOutputInfo(valtype, &typOutput, &typElem, &typIsVarlena);
+
+ fmgr_info(typOutput, &finfo_output);
+
+ return DatumGetCString(FunctionCall3(&finfo_output,
+ value,
+ ObjectIdGetDatum(typElem),
+ Int32GetDatum(-1)));
+}
+
/* ----------
* exec_cast_value Cast a value if required
* ----------
*/
if (valtype != reqtype || reqtypmod != -1)
{
- HeapTuple typetup;
- Form_pg_type typeStruct;
- FmgrInfo finfo_output;
char *extval;
- typetup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(valtype),
- 0, 0, 0);
- if (!HeapTupleIsValid(typetup))
- elog(ERROR, "cache lookup failed for type %u", valtype);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
-
- fmgr_info(typeStruct->typoutput, &finfo_output);
- extval = DatumGetCString(FunctionCall3(&finfo_output,
- value,
- ObjectIdGetDatum(typeStruct->typelem),
- Int32GetDatum(-1)));
+ extval = convert_value_to_string(value, valtype);
value = FunctionCall3(reqinput,
CStringGetDatum(extval),
ObjectIdGetDatum(reqtypelem),
Int32GetDatum(reqtypmod));
pfree(extval);
- ReleaseSysCache(typetup);
}
}
FmgrInfo finfo_input;
getTypeInputInfo(reqtype, &typInput, &typElem);
+
fmgr_info(typInput, &finfo_input);
value = exec_cast_value(value,