* Check for assert violations and error out, if any. */
| 25 | * Check for assert violations and error out, if any. |
| 26 | */ |
| 27 | static void |
| 28 | CheckForAssertViolations(AssertOpState* node, TupleTableSlot* slot) |
| 29 | { |
| 30 | AssertOp* plannode = (AssertOp*) node->ps.plan; |
| 31 | ExprContext* econtext = node->ps.ps_ExprContext; |
| 32 | ResetExprContext(econtext); |
| 33 | /* Arrange for econtext's scan tuple to be the tuple under test */ |
| 34 | econtext->ecxt_outertuple = slot; |
| 35 | /* |
| 36 | * Run in short-lived per-tuple context while computing expressions. |
| 37 | */ |
| 38 | MemoryContext oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); |
| 39 | StringInfoData errorString; |
| 40 | initStringInfo(&errorString); |
| 41 | |
| 42 | ExprState *clause = node->ps.qual; |
| 43 | bool isNull = false; |
| 44 | Datum expr_value = ExecEvalExpr(clause, econtext, &isNull); |
| 45 | |
| 46 | if (!isNull && !DatumGetBool(expr_value)) |
| 47 | { |
| 48 | Value *valErrorMessage = (Value*) list_nth(plannode->errmessage, 0); |
| 49 | |
| 50 | Assert(NULL != valErrorMessage && IsA(valErrorMessage, String) && |
| 51 | 0 < strlen(strVal(valErrorMessage))); |
| 52 | |
| 53 | appendStringInfo(&errorString, "%s\n", strVal(valErrorMessage)); |
| 54 | |
| 55 | ereport(ERROR, |
| 56 | (errcode(plannode->errcode), |
| 57 | errmsg("one or more assertions failed"), |
| 58 | errdetail("%s", errorString.data))); |
| 59 | } |
| 60 | |
| 61 | pfree(errorString.data); |
| 62 | MemoryContextSwitchTo(oldContext); |
| 63 | ResetExprContext(econtext); |
| 64 | } |
| 65 | |
| 66 | /* |
| 67 | * Evaluate Constraints (in node->ps.qual) and project output TupleTableSlot. |
no test coverage detected