Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit675af5c

Browse files
committed
Compute information about EEOP_*_FETCHSOME at expression init time.
Previously this information was computed when JIT compiling anexpression. But the information is useful for assertions in thenon-JIT case too (for assertions), therefore it makes sense to moveit.This will, in a followup commit, allow to treat different slot typesdifferently. E.g. for virtual slots there's no need to generate a JITfunction to deform the slot.Author: Andres FreundDiscussion:https://postgr.es/m/20181105210039.hh4vvi4vwoq5ba2q@alap3.anarazel.de
1 parent1a0586d commit675af5c

File tree

3 files changed

+124
-29
lines changed

3 files changed

+124
-29
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static void ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args,
6565
static void ExecInitExprSlots(ExprState *state, Node *node);
6666
static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info);
6767
static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info);
68+
static void ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op);
6869
static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable,
6970
ExprState *state);
7071
static void ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref,
@@ -2288,21 +2289,30 @@ ExecPushExprSlots(ExprState *state, LastAttnumInfo *info)
22882289
{
22892290
scratch.opcode = EEOP_INNER_FETCHSOME;
22902291
scratch.d.fetch.last_var = info->last_inner;
2292+
scratch.d.fetch.fixed = false;
2293+
scratch.d.fetch.kind = NULL;
22912294
scratch.d.fetch.known_desc = NULL;
2295+
ExecComputeSlotInfo(state, &scratch);
22922296
ExprEvalPushStep(state, &scratch);
22932297
}
22942298
if (info->last_outer > 0)
22952299
{
22962300
scratch.opcode = EEOP_OUTER_FETCHSOME;
22972301
scratch.d.fetch.last_var = info->last_outer;
2302+
scratch.d.fetch.fixed = false;
2303+
scratch.d.fetch.kind = NULL;
22982304
scratch.d.fetch.known_desc = NULL;
2305+
ExecComputeSlotInfo(state, &scratch);
22992306
ExprEvalPushStep(state, &scratch);
23002307
}
23012308
if (info->last_scan > 0)
23022309
{
23032310
scratch.opcode = EEOP_SCAN_FETCHSOME;
23042311
scratch.d.fetch.last_var = info->last_scan;
2312+
scratch.d.fetch.fixed = false;
2313+
scratch.d.fetch.kind = NULL;
23052314
scratch.d.fetch.known_desc = NULL;
2315+
ExecComputeSlotInfo(state, &scratch);
23062316
ExprEvalPushStep(state, &scratch);
23072317
}
23082318
}
@@ -2355,6 +2365,94 @@ get_last_attnums_walker(Node *node, LastAttnumInfo *info)
23552365
(void *) info);
23562366
}
23572367

2368+
/*
2369+
* Compute additional information for EEOP_*_FETCHSOME ops.
2370+
*
2371+
* The goal is to determine whether a slot is 'fixed', that is, every
2372+
* evaluation of the the expression will have the same type of slot, with an
2373+
* equivalent descriptor.
2374+
*/
2375+
static void
2376+
ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
2377+
{
2378+
PlanState *parent = state->parent;
2379+
TupleDescdesc = NULL;
2380+
const TupleTableSlotOps *tts_ops = NULL;
2381+
bool isfixed = false;
2382+
2383+
if (op->d.fetch.known_desc != NULL)
2384+
{
2385+
desc = op->d.fetch.known_desc;
2386+
tts_ops = op->d.fetch.kind;
2387+
isfixed = op->d.fetch.kind != NULL;
2388+
}
2389+
else if (!parent)
2390+
{
2391+
isfixed = false;
2392+
}
2393+
else if (op->opcode == EEOP_INNER_FETCHSOME)
2394+
{
2395+
PlanState *is = innerPlanState(parent);
2396+
2397+
if (parent->inneropsset && !parent->inneropsfixed)
2398+
{
2399+
isfixed = false;
2400+
}
2401+
else if (parent->inneropsset && parent->innerops)
2402+
{
2403+
isfixed = true;
2404+
tts_ops = parent->innerops;
2405+
}
2406+
else if (is)
2407+
{
2408+
tts_ops = ExecGetResultSlotOps(is, &isfixed);
2409+
desc = ExecGetResultType(is);
2410+
}
2411+
}
2412+
else if (op->opcode == EEOP_OUTER_FETCHSOME)
2413+
{
2414+
PlanState *os = outerPlanState(parent);
2415+
2416+
if (parent->outeropsset && !parent->outeropsfixed)
2417+
{
2418+
isfixed = false;
2419+
}
2420+
else if (parent->outeropsset && parent->outerops)
2421+
{
2422+
isfixed = true;
2423+
tts_ops = parent->outerops;
2424+
}
2425+
else if (os)
2426+
{
2427+
tts_ops = ExecGetResultSlotOps(os, &isfixed);
2428+
desc = ExecGetResultType(os);
2429+
}
2430+
}
2431+
else if (op->opcode == EEOP_SCAN_FETCHSOME)
2432+
{
2433+
desc = parent->scandesc;
2434+
2435+
if (parent && parent->scanops)
2436+
tts_ops = parent->scanops;
2437+
2438+
if (parent->scanopsset)
2439+
isfixed = parent->scanopsfixed;
2440+
}
2441+
2442+
if (isfixed && desc != NULL && tts_ops != NULL)
2443+
{
2444+
op->d.fetch.fixed = true;
2445+
op->d.fetch.kind = tts_ops;
2446+
op->d.fetch.known_desc = desc;
2447+
}
2448+
else
2449+
{
2450+
op->d.fetch.fixed = false;
2451+
op->d.fetch.kind = NULL;
2452+
op->d.fetch.known_desc = NULL;
2453+
}
2454+
}
2455+
23582456
/*
23592457
* Prepare step for the evaluation of a whole-row variable.
23602458
* The caller still has to push the step.
@@ -3255,12 +3353,18 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
32553353
/* push deform steps */
32563354
scratch.opcode = EEOP_INNER_FETCHSOME;
32573355
scratch.d.fetch.last_var = maxatt;
3356+
scratch.d.fetch.fixed = false;
32583357
scratch.d.fetch.known_desc = ldesc;
3358+
scratch.d.fetch.kind = lops;
3359+
ExecComputeSlotInfo(state, &scratch);
32593360
ExprEvalPushStep(state, &scratch);
32603361

32613362
scratch.opcode = EEOP_OUTER_FETCHSOME;
32623363
scratch.d.fetch.last_var = maxatt;
3364+
scratch.d.fetch.fixed = false;
32633365
scratch.d.fetch.known_desc = rdesc;
3366+
scratch.d.fetch.kind = rops;
3367+
ExecComputeSlotInfo(state, &scratch);
32643368
ExprEvalPushStep(state, &scratch);
32653369

32663370
/*

‎src/backend/jit/llvm/llvmjit_expr.c

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -276,47 +276,31 @@ llvm_compile_expr(ExprState *state)
276276
LLVMValueRef v_slot;
277277
LLVMBasicBlockRef b_fetch;
278278
LLVMValueRef v_nvalid;
279+
LLVMValueRef l_jit_deform = NULL;
280+
const TupleTableSlotOps *tts_ops = NULL;
279281

280282
b_fetch = l_bb_before_v(opblocks[i + 1],
281283
"op.%d.fetch", i);
282284

283285
if (op->d.fetch.known_desc)
284286
desc = op->d.fetch.known_desc;
285287

286-
if (opcode == EEOP_INNER_FETCHSOME)
287-
{
288-
PlanState *is = innerPlanState(parent);
288+
if (op->d.fetch.fixed)
289+
tts_ops = op->d.fetch.kind;
289290

291+
if (opcode == EEOP_INNER_FETCHSOME)
290292
v_slot = v_innerslot;
291-
292-
if (!desc &&
293-
is &&
294-
is->ps_ResultTupleSlot &&
295-
TTS_FIXED(is->ps_ResultTupleSlot))
296-
desc = is->ps_ResultTupleSlot->tts_tupleDescriptor;
297-
}
298293
else if (opcode == EEOP_OUTER_FETCHSOME)
299-
{
300-
PlanState *os = outerPlanState(parent);
301-
302294
v_slot = v_outerslot;
303-
304-
if (!desc &&
305-
os &&
306-
os->ps_ResultTupleSlot &&
307-
TTS_FIXED(os->ps_ResultTupleSlot))
308-
desc = os->ps_ResultTupleSlot->tts_tupleDescriptor;
309-
}
310295
else
311-
{
312296
v_slot = v_scanslot;
313-
if (!desc && parent)
314-
desc = parent->scandesc;
315-
}
316297

317298
/*
318299
* Check if all required attributes are available, or
319300
* whether deforming is required.
301+
*
302+
* TODO: skip nvalid check if slot is fixed and known to
303+
* be a virtual slot.
320304
*/
321305
v_nvalid =
322306
l_load_struct_gep(b, v_slot,
@@ -336,19 +320,21 @@ llvm_compile_expr(ExprState *state)
336320
* function specific to tupledesc and the exact number of
337321
* to-be-extracted attributes.
338322
*/
339-
if (desc && (context->base.flags & PGJIT_DEFORM))
323+
if (tts_ops &&desc && (context->base.flags & PGJIT_DEFORM))
340324
{
341-
LLVMValueRef params[1];
342-
LLVMValueRef l_jit_deform;
343-
344325
l_jit_deform =
345326
slot_compile_deform(context, desc,
346327
op->d.fetch.last_var);
328+
}
329+
330+
if (l_jit_deform)
331+
{
332+
LLVMValueRef params[1];
333+
347334
params[0] = v_slot;
348335

349336
LLVMBuildCall(b, l_jit_deform,
350337
params, lengthof(params), "");
351-
352338
}
353339
else
354340
{

‎src/include/executor/execExpr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,12 @@ typedef struct ExprEvalStep
262262
{
263263
/* attribute number up to which to fetch (inclusive) */
264264
intlast_var;
265+
/* will the type of slot be the same for every invocation */
266+
boolfixed;
267+
/* tuple descriptor, if known */
265268
TupleDescknown_desc;
269+
/* type of slot, can only be relied upon if fixed is set */
270+
const TupleTableSlotOps *kind;
266271
}fetch;
267272

268273
/* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp