Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the implementation method of getting tuple attribute values when PostgreSQL executes a query?

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

< natts; attnum++) { //获取列值 Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum); if (hasnulls && att_isnull(attnum, bp)) { //null values[attnum] = (Datum) 0; isnull[attnum] = true; slow = true; /* can't use attcacheoff anymore */ continue; } isnull[attnum] = false; if (!slow && thisatt->

Attcacheoff > = 0) off = thisatt- > attcacheoff; else if (thisatt- > attlen = =-1) {/ * We can only cache the offset for a varlena attribute if the * offset is already suitably aligned, so that there would be no * pad bytes in any case: then the offset will be valid for either * an aligned or unaligned value. * varlena: offset is valid whether it is aligned or not. * / if (! slow & & off = = att_align_nominal (off, thisatt- > attalign)) thisatt- > attcacheoff = off; else {off = att_align_pointer (off, thisatt- > attalign,-1, tp + off); slow = true }} else {/ * not varlena, so safe to use att_align_nominal * / / non-varlena: use att_align_nominal off = att_align_nominal (off, thisatt- > attalign); if (! slow) thisatt- > attcacheoff = off } / / get column values values [attnum] = fetchatt (thisatt, tp + off); / / adjust offset off = att_addlength_pointer (off, thisatt- > attlen, tp + off); if (thisatt- > attlen attrs [(I)]) # define fetchatt (A) fetch_att (T, (A)-> attbyval, (A)-> attlen) / * * Same, but work from byval/len parameters rather than Form_pg_attribute. * / # if SIZEOF_DATUM = = 8#define fetch_att (TMagne attbyval Attlen)\ (attbyval)?\ (attlen) = = (int) sizeof (Datum)?\ * ((Datum *) (T))\: (\ (attlen) = = (int) sizeof (int32)?\ Int32GetDatum (* ((int32 *) (T)\:\ (\ (attlen) = (int) sizeof (int16)?\ Int16GetDatum (* ((int16 *) (T)\:\ (\ AssertMacro ((attlen) = = 1) \ CharGetDatum (* ((char *) (T)\)\:\ PointerGetDatum ((char *) (T))\) # else / * SIZEOF_DATUM! = 8 * / # define fetch_att Attlen)\ (attbyval)?\ (attlen) = = (int) sizeof (int32)?\ Int32GetDatum (* ((int32 *) (T)\:\ (attlen) = = (int) sizeof (int16)?\ Int16GetDatum (* ((int16 *) (T)\ :\ (\ AssertMacro ((attlen) = = 1) \ CharGetDatum (* (char *) (T))\)\:\ PointerGetDatum ((char *) (T))\) # endif / * SIZEOF_DATUM = = 8 * / * * DatumGetPointer * Returns pointer value of a datum. * / # define DatumGetPointer (X) ((Pointer) (X)) / * PointerGetDatum * Returns datum representation for a pointer. * / # define PointerGetDatum (X) ((Datum) (X)) III. Tracking analysis

Perform SQL:

[local]: 5432 pg12@testdb=# select * from t_getattrs

Start gdb and enter the breakpoint

(gdb) b slot_deform_heap_tupleBreakpoint 3 at 0x6fdeac: file execTuples.c, line 892. (gdb) cContinuing.Breakpoint 3, slot_deform_heap_tuple (slot=0x12312a0, tuple=0x1231880, offp=0x12312e8, natts=5) at execTuples.c:892892 TupleDesc tupleDesc = slot- > tts_tupleDescriptor (gdb) bt#0 slot_deform_heap_tuple (slot=0x12312a0, tuple=0x1231880, offp=0x12312e8, natts=5) at execTuples.c:892#1 0x00000000006fd7d6 in tts_buffer_heap_getsomeattrs (slot=0x12312a0, natts=5) at execTuples.c:676#2 0x00000000006ff7a9 in slot_getsomeattrs_int (slot=0x12312a0, attnum=5) at execTuples.c:1877#3 0x000000000048ed13 in slot_getsomeattrs (slot=0x12312a0 Attnum=5) at. / src/include/executor/tuptable.h:345#4 0x000000000048ed39 in slot_getallattrs (slot=0x12312a0) at. / src/include/executor/tuptable.h:357#5 0x000000000048f88a in printtup (slot=0x12312a0, self=0x1239a50) at printtup.c:392#6 0x00000000006efc3c in ExecutePlan (estate=0x1230e38, planstate=0x1231090, use_parallel_mode=false, operation=CMD_SELECT, sendTuples=true, numberTuples=0, direction=ForwardScanDirection, dest=0x1239a50, execute_once=true) at execMain.c:1685#7 0x00000000006ed9df in standard_ExecutorRun (queryDesc=0x121b978, direction=ForwardScanDirection) Count=0, execute_once=true) at execMain.c:364#8 0x00000000006ed815 in ExecutorRun (queryDesc=0x121b978, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:308#9 0x00000000008f1010 in PortalRunSelect (portal=0x11b9c08, forward=true, count=0, dest=0x1239a50) at pquery.c:929#10 0x00000000008f0cae in PortalRun (portal=0x11b9c08, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x1239a50, altdest=0x1239a50, completionTag=0x7ffd32962250 ") at pquery.c:770#11 0x00000000008ead35 in exec_simple_query (query_string=0x1152d98" select * from t_getattrs ") At postgres.c:1215#12 0x00000000008eefa5 in PostgresMain (argc=1, argv=0x117fda8, dbname=0x117fbf0 "testdb", username=0x114fab8 "pg12") at postgres.c:4236#13 0x0000000000845915 in BackendRun (port=0x1175bc0) at postmaster.c:4431#14 0x00000000008450f3 in BackendStartup (port=0x1175bc0) at postmaster.c:4122---Type to continue, or q to quit---#15 0x000000000084132f in ServerLoop () at postmaster.c:1704#16 0x0000000000840be5 in PostmasterMain (argc=1, argv=0x114da70) at postmaster.c:1377#17 0x0000000000761469 in main (argc=1, argv=0x114da70) at main.c:228 (gdb) (gdb)

Input parameters

(gdb) p * slot-- > tuple slot$1 = {type = T_TupleTableSlot, tts_flags = 16, tts_nvalid = 0, tts_ops = 0xc3e780, tts_tupleDescriptor = 0x7fe1af2fd7a8, tts_values = 0x1231310, tts_isnull = 0x1231338, tts_mcxt = 0x1230d20, tts_tid = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1}, tts_tableOid = 131110} (gdb) p tuple$2 = (HeapTuple) 0x1231880 (gdb) p * tuple-> tuple $3 = {t_len = 67 T_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1}, t_tableOid = 131110, t_data = 0x7fe18396e438} (gdb) p * offp-> offset $4 = 0 (gdb) p natts-> 5 attributes $5 = 5 (gdb)

Initialize related variables

(gdb) n893 Datum * values = slot- > tts_values; (gdb) 894 bool * isnull = slot- > tts_isnull; (gdb) 895 HeapTupleHeader tup = tuple- > Twitter data; (gdb) p * values$6 = 0 (gdb) p * isnull$7 = false (gdb) n896 bool hasnulls = HeapTupleHasNulls (tuple); (gdb) 900bits8 * bp = tup- > t_bits / * ptr to null bitmap in tuple * / (gdb) 904 natts = Min (HeapTupleHeaderGetNatts (tuple- > t_data), natts); (gdb) p * bp$8 = 0'\ 000' (gdb) n910 attnum = slot- > tts_nvalid; (gdb) p natts$9 = 5 (gdb) n911 if (attnum = = 0) (gdb) p attnum$10 = 0 (gdb)

Execute for the first time, set offset and other information, and initialize tuple data pointer

(gdb) n914 off = 0; (gdb) 915 slow = false; (gdb) 924 tp = (char *) tup + tup- > t_hoff (gdb) p tup- > t_hoff$11 = 24'\ 030' (gdb) p * tup--> Tuple header information $12 = {t_choice = {t_heap = {t_xmin = 14764, t_xmax = 0, t_field3 = {t_cid = 0, t_xvac = 0}}, t_datum = {datum_len_ = 14764, datum_typmod = 0, datum_typeid = 0}}, t_ctid = {ip_blkid = {bi_hi = 0, bi_lo = 0} Ip_posid = 1}, t_infomask2 = 5, t_infomask = 2306, t_hoff = 24'\ 030mm, t_bits = 0x7fe18396e44f ""} (gdb)

Start a loop to get the value of each property

(gdb) n926 for (; attnum

< natts; attnum++)(gdb) 928 Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum);(gdb) 930 if (hasnulls && att_isnull(attnum, bp)) 属性信息 (gdb) p thisatt$13 = (Form_pg_attribute) 0x7fe1af2fd7c0(gdb) p *thisatt$14 = {attrelid = 131110, attname = {data = "id", '\000' }, atttypid = 23, attstattarget = -1, attlen = 4, attnum = 1, attndims = 0, attcacheoff = 0, atttypmod = -1, attbyval = true, attstorage = 112 'p', attalign = 105 'i', attnotnull = false, atthasdef = false, atthasmissing = false, attidentity = 0 '\000', attgenerated = 0 '\000', attisdropped = false, attislocal = true, attinhcount = 0, attcollation = 0}(gdb) 获取第1个属性值,即id的值。注意:fetchatt执行的逻辑是Int32GetDatum(*((int32 *)(T))) (gdb) p thisatt->

Attbyval$18 = true (gdb) p thisatt- > attlen$19 = 4 (gdb) p SIZEOF_DATUM$24 = 8 (gdb) p (int) sizeof (Datum) $26 = 8 (gdb) p (int) sizeof (int32) $27 = 4 (gdb) (gdb) p Int32GetDatum (* (int32 *) (tp+off)) $25 = (int) sizeof (int32)?\ Int32GetDatum (* (int32 *) (T)\ #

Gets the second property value, the value of col_varchar. Note: the logic executed by fetchatt is PointerGetDatum ((char *) (T)

(gdb) n973 if (thisatt- > attlen attcacheoff > = 0) (gdb) 941 off = thisatt- > attcacheoff; (gdb) 969 values [attnum] = fetchatt (thisatt, tp + off) (gdb) p off$29 = 4 (gdb) p PointerGetDatum ((char *) (tp+off)) $30 = 140606552073300 (gdb) x tp+off 5c PointerGetDatum ((char *) (tp+off)) 0x7fe18396e454: 11'\ v '116' t '101' e '115' (gdb) p (char *) PointerGetDatum ((char *) (tp+off)) $32 = 0x7fe18396e454 "\ vtest\ 027test" (gdb)

Gets the second property value, the value of col_char. Note: the logic executed by fetchatt is PointerGetDatum ((char *) (T)

(gdb) n971 off = att_addlength_pointer (off, thisatt- > attlen, tp + off); (gdb) 973 if (thisatt- > attlen attlen$34 =-1 (gdb) n974 slow = true; / * can't use attcacheoff anymore * / (gdb) 926 for (; attnum)

< natts; attnum++)(gdb) 928 Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum);(gdb) 930 if (hasnulls && att_isnull(attnum, bp))(gdb) 938 isnull[attnum] = false;(gdb) 940 if (!slow && thisatt->

Attcacheoff > = 0) (gdb) 942 else if (thisatt- > attlen = =-1) (gdb) 950 if (! slow & & (gdb) 955 off = att_align_pointer (off, thisatt- > attalign,-1, (gdb) 957 slow = true; (gdb) p off$35 = 9 (gdb) n969 values [attnum] = fetchatt (thisatt, tp + off) (gdb) p * thisatt$36 = {attrelid = 131110, attname = {data = "col_char",'\ 000'}, atttypid = 1042, attstattarget =-1, attlen =-1, attnum = 3, attndims = 0, attcacheoff =-1, atttypmod = 14, attbyval = false, attstorage = 120'x, attalign = 105'I, attnotnull = false, atthasdef = false, atthasmissing = false, attidentity = 0'\ 000, attgenerated = 0'\ 000, attisdropped = false, attislocal = true, attinhcount = 0 Attcollation = 100} (gdb) p (char *) PointerGetDatum ((char *) (tp+off)) $37 = 0x7fe18396e459 "\ 027test" (gdb)

Gets the fourth attribute value, that is, the value of col_double. Note: the logic executed by fetchatt is * ((Datum *) (T)

(gdb) n971 off = att_addlength_pointer (off, thisatt- > attlen, tp + off); (gdb) 973 if (thisatt- > attlen tts_nvalid = attnum; (gdb) 981 * offp = off; (gdb) 982 if (slow) (gdb) 983 slot- > tts_flags | = TTS_FLAG_SLOW (gdb) 986} (gdb) tts_buffer_heap_getsomeattrs (slot=0x12312a0, natts=5) at execTuples.c:677677} (gdb) so far, I believe you have a deeper understanding of "how to get tuple attribute values when PostgreSQL executes a query". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report