修改mysql_fdw兼容日期为0的数据

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 日期本来是不能为0的,但mysql在非严格模式下可以设置日期为0,导致pg通过mysql_fdw访问mysql时遇到日期为0的数据会报错,这里给出一种简单的解决办法。

一个项目中,开发同学使用了MySQL的非严格模式,并把表的日期字段缺省值设置成0,最近有个项目需要从PostgreSQL中访问MySQL的数据,使用的mysql_fdw扩展访问mysql中的数据,一遇到日期为0的数据就报错,又不能去修改MySQL库里的数据,万般无奈之下,分析了mysql_fdw的源码,mysql_fdw的数据转换是通过mysql_query.c中的mysql_convert_to_pg函数实现的,于是用了个比较low的方法,遇到日期为0的数据就改成0001-01-01,够用就好,记录下过程。

/** convert_mysql_to_pg:*      Convert MySQL data into PostgreSQL's compatible data types*/Datummysql_convert_to_pg(Oidpgtyp, intpgtypmod, mysql_column*column)
{
Datumvalue_datum;
DatumvalueDatum;
regproctypeinput;
HeapTupletuple;
charstr[MAXDATELEN];
bytea*result;
char*text_result=NULL;
/* get the type's output function */tuple=SearchSysCache1(TYPEOID, ObjectIdGetDatum(pgtyp));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for type%u", pgtyp);
typeinput= ((Form_pg_type) GETSTRUCT(tuple))->typinput;
ReleaseSysCache(tuple);
switch (pgtyp)
    {
/** MySQL gives BIT / BIT(n) data type as decimal value.  The only way* to retrieve this value is to use BIN, OCT or HEX function in MySQL,* otherwise mysql client shows the actual decimal value, which could* be a non - printable character.  For exmple in MySQL** CREATE TABLE t (b BIT(8));* INSERT INTO t SET b = b'1001';* SELECT BIN(b) FROM t;* +--------+* | BIN(b) |* +--------+* | 1001   |* +--------+** PostgreSQL expacts all binary data to be composed of either '0' or* '1'. MySQL gives value 9 hence PostgreSQL reports error.  The* solution is to convert the decimal number into equivalent binary* string.*/caseBYTEAOID:
result= (bytea*) palloc(column->length+VARHDRSZ);
memcpy(VARDATA(result), VARDATA(column->value), column->length);
SET_VARSIZE(result, column->length+VARHDRSZ);
returnPointerGetDatum(result);
caseBITOID:
sprintf(str, "%d", dec_bin(*((int*) column->value)));
valueDatum=CStringGetDatum((char*) str);
break;
caseTEXTOID:
text_result= (char*) palloc(column->length+1);
memcpy(text_result, (char*) column->value, column->length);
text_result[column->length] ='\0';
valueDatum=CStringGetDatum((char*) text_result);
break;
/*以下是增加的代码*/caseDATEOID:
caseTIMESTAMPOID:
caseTIMESTAMPTZOID:
text_result= (char*) palloc(column->length+1);
memcpy(text_result, (char*) column->value, column->length);
text_result[column->length] ='\0';
if(strstr(text_result, "0000-"))
            {
memcpy(text_result, "0001-01-01", strlen("0001-01-01"));
            }
valueDatum=CStringGetDatum((char*) text_result);
break;
default:
valueDatum=CStringGetDatum((char* ) column->value);
    }
value_datum=OidFunctionCall3(typeinput, valueDatum,
ObjectIdGetDatum(pgtyp),
Int32GetDatum(pgtypmod));
if (text_result)
pfree(text_result);
returnvalue_datum;
}
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
16天前
|
缓存 NoSQL 关系型数据库
13- Redis和Mysql如何保证数据⼀致?
该内容讨论了保证Redis和MySQL数据一致性的几种策略。首先提到的两种方法存在不一致风险:先更新MySQL再更新Redis,或先删Redis再更新MySQL。第三种方案是通过MQ异步同步以达到最终一致性,适用于一致性要求较高的场景。项目中根据不同业务需求选择不同方案,如对一致性要求不高的情况不做处理,时效性数据设置过期时间,高一致性需求则使用MQ确保同步,最严格的情况可能涉及分布式事务(如Seata的TCC模式)。
44 6
|
23天前
|
SQL 关系型数据库 MySQL
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
|
30天前
|
关系型数据库 MySQL
elasticsearch对比mysql以及使用工具同步mysql数据全量增量
elasticsearch对比mysql以及使用工具同步mysql数据全量增量
21 0
|
1月前
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
21 1
|
1月前
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
15 1
|
2天前
|
SQL 关系型数据库 MySQL
Spring_jdbc数据连接池(mysql实现增、删、改、查)
Spring_jdbc数据连接池(mysql实现增、删、改、查)
8 0
|
4天前
|
存储 数据可视化 关系型数据库
MySQL字段的时间类型该如何选择?千万数据下性能提升10%~30%🚀
本文探讨MySQL中时间类型的选择,阐述datetime、timestamp、整形时间戳等类型特点以及它们在千万级数据量下的查询性能
MySQL字段的时间类型该如何选择?千万数据下性能提升10%~30%🚀
|
29天前
|
关系型数据库 MySQL
MySQL查询当天昨天明天本月上月今年等数据
MySQL查询当天昨天明天本月上月今年等数据
19 2
|
30天前
|
关系型数据库 MySQL 开发工具
MySQL分组后,组内排序,然后取每组的第一条数据
MySQL分组后,组内排序,然后取每组的第一条数据
17 1
|
30天前
|
canal SQL 关系型数据库
MySQL数据直接实时同步到ES
MySQL数据直接实时同步到ES
33 0