PostgreSQL如何实现输出
发表于:2025-11-10 作者:千家信息网编辑
千家信息网最后更新 2025年11月10日,这篇文章主要介绍了PostgreSQL如何实现输出,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、输出参照current_date函
千家信息网最后更新 2025年11月10日PostgreSQL如何实现输出
这篇文章主要介绍了PostgreSQL如何实现输出,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
一、输出
参照current_date函数,首先通过日志跟踪其parse tree,重点关注targetList
2019-04-19 17:06:15.591 CST,"xdb","testdb",1693,"[local]",5cb98b16.69d,3,"SELECT",2019-04-19 16:47:18 CST,3/4,0,LOG,00000,"parse tree:"," {QUERY :commandType 1 ... :targetList ( {TARGETENTRY :expr {SQLVALUEFUNCTION :op 0 :type 1082 :typmod -1 :location 7 } :resno 1 :resname current_date :ressortgroupref 0 :resorigtbl 0 :resorigcol 0 :resjunk false } ) ... :stmt_len 27 }分析源代码,找到与输出相关的文件是src/backend/parser/parse_target.c,相关的函数为transformTargetEntry,跟踪此函数,打印调用栈:
(gdb) bt#0 transformTargetEntry (pstate=0x16afae8, node=0x16af770, expr=0x0, exprKind=EXPR_KIND_SELECT_TARGET, colname=0x0, resjunk=false) at parse_target.c:93#1 0x000000000060b1f9 in transformTargetList (pstate=0x16afae8, targetlist=0x16af828, exprKind=EXPR_KIND_SELECT_TARGET) at parse_target.c:191#2 0x00000000005b1e3a in transformSelectStmt (pstate=0x16afae8, stmt=0x16af938) at analyze.c:1243#3 0x00000000005b03db in transformStmt (pstate=0x16afae8, parseTree=0x16af938) at analyze.c:301#4 0x00000000005b02b6 in transformOptionalSelectInto (pstate=0x16afae8, parseTree=0x16af938) at analyze.c:246#5 0x00000000005b0174 in transformTopLevelStmt (pstate=0x16afae8, parseTree=0x16afa50) at analyze.c:196#6 0x00000000005affcc in parse_analyze (parseTree=0x16afa50, sourceText=0x16aed78 "select current_date from t1;", paramTypes=0x0, numParams=0, queryEnv=0x0) at analyze.c:116#7 0x00000000008bb78c in pg_analyze_and_rewrite (parsetree=0x16afa50, query_string=0x16aed78 "select current_date from t1;", paramTypes=0x0, numParams=0, queryEnv=0x0) at postgres.c:689#8 0x00000000008bbddd in exec_simple_query (query_string=0x16aed78 "select current_date from t1;") at postgres.c:1070#9 0x00000000008c01f3 in PostgresMain (argc=1, argv=0x16dcd28, dbname=0x16dcb90 "testdb", username=0x16aba98 "xdb") at postgres.c:4182#10 0x000000000081e0ce in BackendRun (port=0x16d0b50) at postmaster.c:4361#11 0x000000000081d841 in BackendStartup (port=0x16d0b50) at postmaster.c:4033#12 0x0000000000819c3b in ServerLoop () at postmaster.c:1706#13 0x00000000008194f1 in PostmasterMain (argc=1, argv=0x16a9a50) at postmaster.c:1379#14 0x0000000000742993 in main (argc=1, argv=0x16a9a50) at main.c:228
其中FigureColnameInternal函数为current_date设置输出列名,添加以下代码,则实现输出sysdate:
//Hacker : 添加系统列case SVFOP_ZZ_SYSDATE: *name = "sysdate";//zz_sysdate -> sysdate return 2;
相关源码解读
/* * transformTargetEntry() * Transform any ordinary "expression-type" node into a targetlist entry. * This is exported so that parse_clause.c can generate targetlist entries * for ORDER/GROUP BY items that are not already in the targetlist. * 转换所有普通的"表达式类型expression-type"节点为tagetlist条目. * TargetEntry作为输出参数以便parse_clause.c * 可以为ORDER/GROUP BY等未在targetlist中的items生成targetlist条目 * * node the (untransformed) parse tree for the value expression. * node 未经变换的值表达式 * * expr the transformed expression, or NULL if caller didn't do it yet. * expr 已转换的表达式,如调用者未转换则为NULL * * exprKind expression kind (EXPR_KIND_SELECT_TARGET, etc) * exprKind 表达式类型(如EXPR_KIND_SELECT_TARGET等) * * colname the column name to be assigned, or NULL if none yet set. * colname 分配的列名或者为NULL * * resjunk true if the target should be marked resjunk, ie, it is not * wanted in the final projected tuple. * resjunk 如目标应标记为resjunk,则为T,比如该列不希望投影为最终的元组 */TargetEntry *transformTargetEntry(ParseState *pstate, Node *node, Node *expr, ParseExprKind exprKind, char *colname, bool resjunk){ /* Transform the node if caller didn't do it already */ //expr为NULL,则转换之 if (expr == NULL) { /* * If it's a SetToDefault node and we should allow that, pass it * through unmodified. (transformExpr will throw the appropriate * error if we're disallowing it.) */ if (exprKind == EXPR_KIND_UPDATE_SOURCE && IsA(node, SetToDefault)) expr = node; else expr = transformExpr(pstate, node, exprKind); } if (colname == NULL && !resjunk) { /* * Generate a suitable column name for a column without any explicit * 'AS ColumnName' clause. * 如非显式指定列名(AS ColumnName),产生一个合适的列名 */ colname = FigureColname(node); } //返回TargetEntry return makeTargetEntry((Expr *) expr, (AttrNumber) pstate->p_next_resno++, colname, resjunk);}/* * FigureColname - * if the name of the resulting column is not specified in the target * list, we have to guess a suitable name. The SQL spec provides some * guidance, but not much... * * Note that the argument is the *untransformed* parse tree for the target * item. This is a shade easier to work with than the transformed tree. */char *FigureColname(Node *node){ char *name = NULL; (void) FigureColnameInternal(node, &name); if (name != NULL) return name; /* default result if we can't guess anything */ return "?column?";}/* * FigureColnameInternal - * internal workhorse for FigureColname * * Return value indicates strength of confidence in result: * 0 - no information * 1 - second-best name choice * 2 - good name choice * The return value is actually only used internally. * If the result isn't zero, *name is set to the chosen name. */static intFigureColnameInternal(Node *node, char **name){ int strength = 0; if (node == NULL) return strength; switch (nodeTag(node)) { ... case T_SQLValueFunction: /* make these act like a function or variable */ switch (((SQLValueFunction *) node)->op) { case SVFOP_CURRENT_DATE: *name = "current_date"; return 2; ... //Hacker : 添加系统列 case SVFOP_ZZ_SYSDATE: *name = "sysdate";//zz_sysdate -> sysdate return 2; } break; ... }}感谢你能够认真阅读完这篇文章,希望小编分享的"PostgreSQL如何实现输出"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
输出
函数
篇文章
表达式
条目
类型
系统
跟踪
合适
普通
代码
价值
兴趣
参数
同时
文件
日志
更多
朋友
未经
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
山东 网络安全公司
湖南虚拟服务器管理软件
郑州第三方软件开发服务
数据库技术应用于那些
数据库可视化图形工具怎么使用
北京图胜网络技术有限公司余满连
数据库设计三大范式
自考网络安全与执法专业
邯郸软件开发费用是多少
ef实体进行数据库连接
河北服务器硬盘报价
db2 查看当前数据库
公安部网络安全技术中心
怎么看服务器管理网口状态
机电工程系校园网络安全宣传
电脑和服务器连不上网
戴尔t440服务器开机按钮在哪
操作数据库的实验心得
数字化软件开发岗位
什么是服务器维护
网络安全知识小学
sql数据库怎么存储负数
网络安全态势感知总结
达梦数据库开启ssl
在我的世界服务器里假装挂机
电脑的网络安全模式重启
如何建立企业共享服务器
数据库表的管理实验报告心得
杭州钱米网络技术有限公司
服务器snmp监控日志