63 Datum *resv,
bool *resnull);
65 Oid funcid,
Oid inputcollid,
76 Datum *resv,
bool *resnull);
80 Datum *resv,
bool *resnull);
84 int transno,
int setno,
int setoff,
bool ishash,
263 foreach(lc, adjust_jumps)
378 foreach(lc, targetList)
383 bool isSafeVar =
false;
393 if (tle->
expr != NULL &&
395 ((
Var *) tle->
expr)->varattno > 0)
401 if (inputDesc == NULL)
403 else if (attnum <= inputDesc->natts)
412 if (!attr->attisdropped && variable->
vartype == attr->atttypid)
422 switch (variable->
varno)
540 foreach(lc, subTargetList)
549 elog(
ERROR,
"subplan target list is out of order");
556 elog(
ERROR,
"targetColnos does not match subplan target list");
564 foreach(lc, targetColnos)
582 if (attr->attisdropped)
598 forboth(lc, subTargetList, lc2, targetColnos)
609 if (targetattnum <= 0 || targetattnum > relDesc->
natts)
611 (
errcode(ERRCODE_DATATYPE_MISMATCH),
612 errmsg(
"table row type and query-specified row type do not match"),
613 errdetail(
"Query has too many columns.")));
616 if (attr->attisdropped)
618 (
errcode(ERRCODE_DATATYPE_MISMATCH),
619 errmsg(
"table row type and query-specified row type do not match"),
620 errdetail(
"Query provides a value for a dropped column at ordinal position %d.",
624 (
errcode(ERRCODE_DATATYPE_MISMATCH),
625 errmsg(
"table row type and query-specified row type do not match"),
626 errdetail(
"Table has type %s at ordinal position %d, but query expects %s.",
648 if (attr->attisdropped)
847 Datum *resv,
bool *resnull)
855 Assert(resv != NULL && resnull != NULL);
876 switch (variable->
varno)
897 switch (variable->
varno)
972 elog(
ERROR,
"unrecognized paramkind: %d",
995 elog(
ERROR,
"Aggref found in non-Agg plan node");
1009 elog(
ERROR,
"GroupingFunc found in non-Agg plan node");
1029 wfstate->
wfunc = wfunc;
1055 (
errcode(ERRCODE_WINDOWING_ERROR),
1056 errmsg(
"window function calls cannot be nested")));
1061 elog(
ERROR,
"WindowFunc found in non-WindowAgg plan node");
1286 foreach(lc, boolexpr->
args)
1294 switch (boolexpr->
boolop)
1301 else if (off + 1 == nargs)
1311 else if (off + 1 == nargs)
1335 foreach(lc, adjust_jumps)
1352 elog(
ERROR,
"SubPlan found with no parent plan");
1397 ncolumns = tupDesc->
natts;
1402 nulls = (
bool *)
palloc(
sizeof(
bool) * ncolumns);
1425 Datum *save_innermost_caseval;
1426 bool *save_innermost_casenull;
1428 if (fieldnum <= 0 || fieldnum > ncolumns)
1429 elog(
ERROR,
"field number %d is out of range in FieldStore",
1462 &values[fieldnum - 1],
1463 &nulls[fieldnum - 1]);
1515 &iofunc, &typisvarlena);
1527 &iofunc, &typioparam);
1538 fcinfo_in = scratch.
d.
iocoerce.fcinfo_data_in;
1560 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1561 errmsg(
"target type is not an array")));
1646 Datum *caseval = NULL;
1647 bool *casenull = NULL;
1655 if (caseExpr->
arg != NULL)
1659 casenull =
palloc(
sizeof(
bool));
1689 foreach(lc, caseExpr->
args)
1692 Datum *save_innermost_caseval;
1693 bool *save_innermost_casenull;
1719 scratch.
d.
jump.jumpdone = -1;
1731 scratch.
d.
jump.jumpdone = -1;
1756 foreach(lc, adjust_jumps)
1803 (
bool *)
palloc(
sizeof(
bool) * nelems);
1865 Assert(nelems <= tupdesc->natts);
1866 nelems =
Max(nelems, tupdesc->
natts);
1873 scratch.
d.
row.tupdesc = tupdesc;
1876 scratch.
d.
row.elemvalues =
1878 scratch.
d.
row.elemnulls =
1879 (
bool *)
palloc(
sizeof(
bool) * nelems);
1881 memset(scratch.
d.
row.elemnulls,
true,
sizeof(
bool) * nelems);
1885 foreach(l, rowexpr->
args)
1890 if (!att->attisdropped)
1900 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1901 errmsg(
"ROW() column has type %s instead of type %s",
1917 &scratch.
d.
row.elemvalues[i],
1918 &scratch.
d.
row.elemnulls[i]);
1950 l_right_expr, rcexpr->
rargs,
1951 l_opno, rcexpr->
opnos,
1976 elog(
ERROR,
"missing support function %d(%u,%u) in opfamily %u",
1985 inputcollid, NULL, NULL);
2031 foreach(lc, adjust_jumps)
2061 foreach(lc, coalesce->
args)
2070 scratch.
d.
jump.jumpdone = -1;
2084 foreach(lc, adjust_jumps)
2111 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
2112 errmsg(
"could not identify a comparison function for type %s",
2135 (
bool *)
palloc(
sizeof(
bool) * nelems);
2136 scratch.
d.
minmax.nelems = nelems;
2139 scratch.
d.
minmax.finfo = finfo;
2140 scratch.
d.
minmax.fcinfo_data = fcinfo;
2144 foreach(lc, minmaxexpr->
args)
2149 &scratch.
d.
minmax.values[off],
2150 &scratch.
d.
minmax.nulls[off]);
2187 (
bool *)
palloc(
sizeof(
bool) * nnamed);
2191 scratch.
d.
xmlexpr.named_argvalue = NULL;
2192 scratch.
d.
xmlexpr.named_argnull = NULL;
2200 (
bool *)
palloc(
sizeof(
bool) * nargs);
2215 &scratch.
d.
xmlexpr.named_argvalue[off],
2216 &scratch.
d.
xmlexpr.named_argnull[off]);
2221 foreach(arg, xexpr->
args)
2256 elog(
ERROR,
"unrecognized nulltesttype: %d",
2306 elog(
ERROR,
"unrecognized booltesttype: %d",
2362 elog(
ERROR,
"unrecognized node type: %d",
2425 (
errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2426 errmsg_plural(
"cannot pass more than %d argument to a function",
2427 "cannot pass more than %d arguments to a function",
2434 flinfo = scratch->
d.
func.finfo;
2435 fcinfo = scratch->
d.
func.fcinfo_data;
2443 nargs, inputcollid, NULL, NULL);
2447 scratch->
d.
func.nargs = nargs;
2452 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2453 errmsg(
"set-valued function called in context that cannot accept a set"),
2485 if (pgstat_track_functions <= flinfo->fn_stats)
2536 scratch.
d.
fetch.fixed =
false;
2537 scratch.
d.
fetch.kind = NULL;
2538 scratch.
d.
fetch.known_desc = NULL;
2546 scratch.
d.
fetch.fixed =
false;
2547 scratch.
d.
fetch.kind = NULL;
2548 scratch.
d.
fetch.known_desc = NULL;
2556 scratch.
d.
fetch.fixed =
false;
2557 scratch.
d.
fetch.kind = NULL;
2558 scratch.
d.
fetch.known_desc = NULL;
2577 switch (variable->
varno)
2627 bool isfixed =
false;
2634 if (op->
d.
fetch.known_desc != NULL)
2636 desc = op->
d.
fetch.known_desc;
2637 tts_ops = op->
d.
fetch.kind;
2638 isfixed = op->
d.
fetch.kind != NULL;
2695 if (isfixed && desc != NULL && tts_ops != NULL)
2697 op->
d.
fetch.fixed =
true;
2698 op->
d.
fetch.kind = tts_ops;
2699 op->
d.
fetch.known_desc = desc;
2703 op->
d.
fetch.fixed =
false;
2705 op->
d.
fetch.known_desc = NULL;
2762 bool junk_filter_needed =
false;
2772 junk_filter_needed =
true;
2778 if (junk_filter_needed)
2811 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2812 errmsg(
"cannot subscript type %s because it does not support subscripting",
2820 (nupper + nlower) * (
sizeof(
Datum) +
2830 ptr += nupper *
sizeof(
Datum);
2832 ptr += nlower *
sizeof(
Datum);
2834 ptr += nupper *
sizeof(
bool);
2836 ptr += nlower *
sizeof(
bool);
2838 ptr += nupper *
sizeof(
bool);
2848 memset(&methods, 0,
sizeof(methods));
2849 sbsroutines->
exec_setup(sbsref, sbsrefstate, &methods);
2867 scratch->
d.
jump.jumpdone = -1;
2875 foreach(lc, sbsref->refupperindexpr)
2898 foreach(lc, sbsref->reflowerindexpr)
2933 Datum *save_innermost_caseval;
2934 bool *save_innermost_casenull;
2939 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2940 errmsg(
"type %s does not support subscripted assignment",
2961 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2962 errmsg(
"type %s does not support subscripted assignment",
2966 scratch->
d.
sbsref.state = sbsrefstate;
2986 scratch->
d.
sbsref.state = sbsrefstate;
2994 scratch->
d.
sbsref.state = sbsrefstate;
2999 foreach(lc, adjust_jumps)
3107 Datum *domainval = NULL;
3108 bool *domainnull = NULL;
3109 Datum *save_innermost_domainval;
3110 bool *save_innermost_domainnull;
3127 (
bool *)
palloc(
sizeof(
bool));
3134 if (domainval == NULL)
3146 domainnull = (
bool *)
palloc(
sizeof(
bool));
3151 scratch2.
resnull = domainnull;
3160 domainnull = resnull;
3189 elog(
ERROR,
"unrecognized constraint type: %d",
3212 bool doSort,
bool doHash,
bool nullcheck)
3230 for (
int transno = 0; transno < aggstate->
numtrans; transno++)
3250 for (
int transno = 0; transno < aggstate->
numtrans; transno++)
3256 bool *strictnulls = NULL;
3273 scratch.
d.
jump.jumpdone = -1;
3295 strictargs = trans_fcinfo->
args + 1;
3358 strictargs = trans_fcinfo->
args + 1;
3387 strictnulls = &state->
resnull;
3399 strictnulls = nulls;
3406 &values[argno], &nulls[argno]);
3439 int processGroupingSets =
Max(phase->
numsets, 1);
3442 for (
int setno = 0; setno < processGroupingSets; setno++)
3445 pertrans, transno, setno, setoff,
false,
3462 for (
int setno = 0; setno < numHashes; setno++)
3465 pertrans, transno, setno, setoff,
true,
3472 foreach(bail, adjust_bailout)
3516 int transno,
int setno,
int setoff,
bool ishash,
3520 int adjust_jumpnull = -1;
3603 scratch->
d.
agg_trans.aggcontext = aggcontext;
3607 if (adjust_jumpnull != -1)
3633 const Oid *eqfunctions,
3634 const Oid *collations,
3658 for (
int natt = 0; natt < numCols; natt++)
3660 int attno = keyColIdx[natt];
3669 scratch.
d.
fetch.last_var = maxatt;
3670 scratch.
d.
fetch.fixed =
false;
3671 scratch.
d.
fetch.known_desc = ldesc;
3672 scratch.
d.
fetch.kind = lops;
3677 scratch.
d.
fetch.last_var = maxatt;
3678 scratch.
d.
fetch.fixed =
false;
3679 scratch.
d.
fetch.known_desc = rdesc;
3680 scratch.
d.
fetch.kind = rops;
3688 for (
int natt = numCols; --natt >= 0;)
3690 int attno = keyColIdx[natt];
3693 Oid foid = eqfunctions[natt];
3694 Oid collid = collations[natt];
3712 collid, NULL, NULL);
3716 scratch.
d.
var.attnum = attno - 1;
3717 scratch.
d.
var.vartype = latt->atttypid;
3724 scratch.
d.
var.attnum = attno - 1;
3725 scratch.
d.
var.vartype = ratt->atttypid;
3732 scratch.
d.
func.finfo = finfo;
3733 scratch.
d.
func.fcinfo_data = fcinfo;
3735 scratch.
d.
func.nargs = 2;
3751 foreach(lc, adjust_jumps)
3789 const Oid *eqfunctions,
3790 const Oid *collations,
3791 const List *param_exprs,
3809 scratch.
d.
fetch.last_var = maxatt;
3810 scratch.
d.
fetch.fixed =
false;
3811 scratch.
d.
fetch.known_desc = desc;
3812 scratch.
d.
fetch.kind = lops;
3817 scratch.
d.
fetch.last_var = maxatt;
3818 scratch.
d.
fetch.fixed =
false;
3819 scratch.
d.
fetch.known_desc = desc;
3820 scratch.
d.
fetch.kind = rops;
3824 for (
int attno = 0; attno < maxatt; attno++)
3827 Oid foid = eqfunctions[attno];
3828 Oid collid = collations[attno];
3846 collid, NULL, NULL);
3850 scratch.
d.
var.attnum = attno;
3851 scratch.
d.
var.vartype = att->atttypid;
3858 scratch.
d.
var.attnum = attno;
3859 scratch.
d.
var.vartype = att->atttypid;
3866 scratch.
d.
func.finfo = finfo;
3867 scratch.
d.
func.fcinfo_data = fcinfo;
3869 scratch.
d.
func.nargs = 2;
3885 foreach(lc, adjust_jumps)
struct ExprEvalStep::@49::@86 subplan
static void ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest, ExprState *state, Datum *resv, bool *resnull)
struct ExprEvalStep::@49::@52 wholerow
struct ExprEvalStep::@49::@80 scalararrayop
#define IsA(nodeptr, _type_)
static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
const TupleTableSlotOps * innerops
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
struct PlanState * parent
#define forboth(cell1, list1, cell2, list2)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
ExprState * ExecInitCheck(List *qual, PlanState *parent)
int exprLocation(const Node *expr)
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
struct ExprEvalStep::@49::@50 fetch
DomainConstraintType constrainttype
ExprState * ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, int numCols, const AttrNumber *keyColIdx, const Oid *eqfunctions, const Oid *collations, PlanState *parent)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Oid get_element_type(Oid typid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
#define PointerGetDatum(X)
struct ExprEvalStep * steps
#define TupleDescAttr(tupdesc, i)
SubscriptExecSetup exec_setup
void ExecReadyInterpretedExpr(ExprState *state)
struct ExprEvalStep::@49::@57 boolexpr
bool * innermost_casenull
ExprState * ExecPrepareCheck(List *qual, EState *estate)
struct ExprEvalStep::@49::@58 qualexpr
ExecEvalSubroutine sbs_fetch
ExprState * ExecBuildParamSetEqual(TupleDesc desc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, const Oid *eqfunctions, const Oid *collations, const List *param_exprs, PlanState *parent)
#define SizeForFunctionCallInfo(nargs)
static bool isAssignmentIndirectionExpr(Expr *expr)
const TupleTableSlotOps TTSOpsVirtual
Expr * expression_planner(Expr *expr)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
struct ExprEvalStep::@49::@72 rowcompare_final
int errcode(int sqlerrcode)
struct ExprEvalStep::@49::@74 fieldselect
ExecEvalSubroutine sbs_fetch_old
struct ExprEvalStep::@49::@83 aggref
struct ExprEvalStep::@49::@67 nextvalueexpr
Datum * innermost_domainval
AggStatePerTrans pertrans
ExecEvalSubroutine sbs_assign
TupleTableSlot * resultslot
#define OidIsValid(objectId)
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
#define DO_AGGSPLIT_COMBINE(as)
FunctionCallInfo transfn_fcinfo
struct ExprEvalStep::@49::@71 rowcompare_step
const struct SubscriptRoutines * getSubscriptingRoutines(Oid typid, Oid *typelemp)
struct ExprEvalStep::@49::@51 var
bool * innermost_domainnull
ExprState * ExecInitQual(List *qual, PlanState *parent)
SubPlanState * ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
struct ExprEvalStep::@49::@89 agg_plain_pergroup_nullcheck
static void ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, ExprState *state, Datum *resv, bool *resnull)
struct ExprEvalStep::@49::@88 agg_strict_input_check
ParamCompileHook paramCompile
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
MemoryContext es_query_cxt
static void convert(const int32 val, char *const buf)
struct ExprEvalStep::@49::@85 window_func
#define ObjectIdGetDatum(X)
union ExprEvalStep::@49 d
char * get_func_name(Oid funcid)
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
struct ExprEvalStep::@49::@61 param
void fmgr_info(Oid functionId, FmgrInfo *finfo)
static void ExecInitExprSlots(ExprState *state, Node *node)
#define lfirst_node(type, lc)
#define outerPlanState(node)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
struct ExprEvalStep::@49::@55 constval
struct ExprEvalStep::@49::@90 agg_trans
struct ExprEvalStep::@49::@79 convert_rowtype
const TupleTableSlotOps * scanops
void check_stack_depth(void)
ExprState * ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)
int errdetail(const char *fmt,...)
#define fmgr_info_set_expr(expr, finfo)
List * ExecInitExprList(List *nodes, PlanState *parent)
ExprState * ExecPrepareQual(List *qual, EState *estate)
FormData_pg_attribute * Form_pg_attribute
MemoryContext CurrentMemoryContext
Datum * innermost_caseval
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
struct ExprEvalStep::@49::@76 sbsref_subscript
List * lappend_int(List *list, int datum)
#define InvokeFunctionExecuteHook(objectId)
List * ExecPrepareExprList(List *nodes, EState *estate)
List * lappend(List *list, void *datum)
static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info)
struct ExprEvalStep::@49::@78 domaincheck
struct ExprEvalStep::@49::@84 grouping_func
static void ExecInitExprRec(Expr *node, ExprState *state, Datum *resv, bool *resnull)
struct ExprEvalStep::@49::@69 arraycoerce
ExprContext * hashcontext
struct ExprEvalStep::@49::@53 assign_var
void * palloc0(Size size)
struct ExprEvalStep::@49::@75 fieldstore
BoolTestType booltesttype
static bool ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
Expr * make_ands_explicit(List *andclauses)
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
static void ExecReadyExpr(ExprState *state)
bool jit_compile_expr(struct ExprState *state)
struct ExprEvalStep::@49::@63 casetest
struct ExprEvalStep::@49::@56 func
NullTestType nulltesttype
struct ExprEvalStep::@49::@64 make_readonly
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
#define ereport(elevel,...)
int executor_errposition(EState *estate, int location)
#define TYPECACHE_CMP_PROC
struct ExprEvalStep::@49::@82 xmlexpr
ExprContext ** aggcontexts
#define Assert(condition)
FunctionCallInfo deserialfn_fcinfo
struct ExprEvalStep::@49::@81 hashedscalararrayop
void DecrTupleDescRefCount(TupleDesc tupdesc)
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref, MemoryContext refctx, bool need_exprstate)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Oid exprType(const Node *expr)
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
struct ExprEvalStep::@49::@60 nulltest_row
static int list_length(const List *l)
static void ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid, Oid inputcollid, ExprState *state)
struct ExprEvalStep::@49::@77 sbsref
struct LastAttnumInfo LastAttnumInfo
struct ExprEvalStep::@49::@66 sqlvaluefunction
Bitmapset * bms_add_member(Bitmapset *a, int x)
void * repalloc(void *pointer, Size size)
TupleDesc ExecGetResultType(PlanState *planstate)
#define InvalidAttrNumber
struct ExprEvalStep::@49::@59 jump
struct ExprEvalStep::@49::@70 row
static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info)
static Datum values[MAXATTR]
struct ExprEvalStep::@49::@68 arrayexpr
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
int16 get_typlen(Oid typid)
TupleDesc ExecTypeFromExprList(List *exprList)
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
int errmsg(const char *fmt,...)
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
#define forfive(cell1, list1, cell2, list2, cell3, list3, cell4, list4, cell5, list5)
bool ExecCheck(ExprState *state, ExprContext *econtext)
ParamListInfo es_param_list_info
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
struct ExprEvalStep::@49::@54 assign_tmp
struct ExprEvalStep::@49::@65 iocoerce
struct ExprEvalStep::@49::@87 agg_deserialize
TupleTableSlot * sortslot
ExecEvalBoolSubroutine sbs_check_subscripts
#define innerPlanState(node)
ProjectionInfo * ExecBuildUpdateProjection(List *subTargetList, List *targetColnos, TupleDesc relDesc, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent)
ExprContext * pi_exprContext
bool bms_is_member(int x, const Bitmapset *a)
void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
JunkFilter * ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
struct ExprEvalStep::@49::@73 minmax
const TupleTableSlotOps * outerops
ExprState * ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, bool doSort, bool doHash, bool nullcheck)
TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod)
static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, ExprEvalStep *scratch, FunctionCallInfo fcinfo, AggStatePerTrans pertrans, int transno, int setno, int setoff, bool ishash, bool nullcheck)