⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formatting.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
				{					sscanf(inout, "%d", &tmfc->ww);					return strdigits_len(inout) + SKIP_THth(suf);				}				else				{					sscanf(inout, "%02d", &tmfc->ww);					return 2 + SKIP_THth(suf);				}			}			break;		case DCH_IW:			if (is_to_char)			{				sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,						date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday));				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				if (S_FM(suf) || is_next_separator(node))				{					sscanf(inout, "%d", &tmfc->iw);					return strdigits_len(inout) + SKIP_THth(suf);				}				else				{					sscanf(inout, "%02d", &tmfc->iw);					return 2 + SKIP_THth(suf);				}			}			break;		case DCH_Q:			if (is_to_char)			{				if (!tm->tm_mon)					return -1;				sprintf(inout, "%d", (tm->tm_mon - 1) / 3 + 1);				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				sscanf(inout, "%1d", &tmfc->q);				return 1 + SKIP_THth(suf);			}			break;		case DCH_CC:			if (is_to_char)			{				i = tm->tm_year / 100 + ((is_interval) ? 0 : 1);				if (i <= 99 && i >= -99)					sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, i);				else					sprintf(inout, "%d", i);				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				if (S_FM(suf) || is_next_separator(node))				{					sscanf(inout, "%d", &tmfc->cc);					return strdigits_len(inout) + SKIP_THth(suf);				}				else				{					sscanf(inout, "%02d", &tmfc->cc);					return 2 + SKIP_THth(suf);				}			}			break;		case DCH_Y_YYY:			if (is_to_char)			{				i = ADJUST_YEAR(tm->tm_year, is_interval) / 1000;				sprintf(inout, "%d,%03d", i, ADJUST_YEAR(tm->tm_year, is_interval) - (i * 1000));				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				int			cc;				sscanf(inout, "%d,%03d", &cc, &tmfc->year);				tmfc->year += (cc * 1000);				tmfc->yysz = 4;				return strdigits_len(inout) + 4 + SKIP_THth(suf);			}			break;		case DCH_YYYY:		case DCH_IYYY:			if (is_to_char)			{				if (tm->tm_year <= 9999 && tm->tm_year >= -9998)					sprintf(inout, "%0*d",							S_FM(suf) ? 0 : 4,							arg == DCH_YYYY ?							ADJUST_YEAR(tm->tm_year, is_interval) :							ADJUST_YEAR(date2isoyear(													 tm->tm_year,													 tm->tm_mon,												 tm->tm_mday), is_interval));				else					sprintf(inout, "%d",							arg == DCH_YYYY ?							ADJUST_YEAR(tm->tm_year, is_interval) :							ADJUST_YEAR(date2isoyear(													 tm->tm_year,													 tm->tm_mon,												 tm->tm_mday), is_interval));				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				if (S_FM(suf) || is_next_separator(node))				{					sscanf(inout, "%d", &tmfc->year);					tmfc->yysz = 4;					return strdigits_len(inout) + SKIP_THth(suf);				}				else				{					sscanf(inout, "%04d", &tmfc->year);					tmfc->yysz = 4;					return 4 + SKIP_THth(suf);				}			}			break;		case DCH_YYY:		case DCH_IYY:			if (is_to_char)			{				snprintf(buff, sizeof(buff), "%03d",						 arg == DCH_YYY ?						 ADJUST_YEAR(tm->tm_year, is_interval) :						 ADJUST_YEAR(date2isoyear(tm->tm_year,												  tm->tm_mon, tm->tm_mday),									 is_interval));				i = strlen(buff);				strcpy(inout, buff + (i - 3));				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				sscanf(inout, "%03d", &tmfc->year);				/*				 * 3-digit year: '100' ... '999' = 1100 ... 1999 '000' ...				 * '099' = 2000 ... 2099				 */				if (tmfc->year >= 100)					tmfc->year += 1000;				else					tmfc->year += 2000;				tmfc->yysz = 3;				return 3 + SKIP_THth(suf);			}			break;		case DCH_YY:		case DCH_IY:			if (is_to_char)			{				snprintf(buff, sizeof(buff), "%02d",						 arg == DCH_YY ?						 ADJUST_YEAR(tm->tm_year, is_interval) :						 ADJUST_YEAR(date2isoyear(tm->tm_year,												  tm->tm_mon, tm->tm_mday),									 is_interval));				i = strlen(buff);				strcpy(inout, buff + (i - 2));				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				sscanf(inout, "%02d", &tmfc->year);				/*				 * 2-digit year: '00' ... '69'	= 2000 ... 2069 '70' ... '99'				 * = 1970 ... 1999				 */				if (tmfc->year < 70)					tmfc->year += 2000;				else					tmfc->year += 1900;				tmfc->yysz = 2;				return 2 + SKIP_THth(suf);			}			break;		case DCH_Y:		case DCH_I:			if (is_to_char)			{				snprintf(buff, sizeof(buff), "%1d",						 arg == DCH_Y ?						 ADJUST_YEAR(tm->tm_year, is_interval) :						 ADJUST_YEAR(date2isoyear(tm->tm_year,												  tm->tm_mon, tm->tm_mday),									 is_interval));				i = strlen(buff);				strcpy(inout, buff + (i - 1));				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				sscanf(inout, "%1d", &tmfc->year);				/*				 * 1-digit year: always +2000				 */				tmfc->year += 2000;				tmfc->yysz = 1;				return 1 + SKIP_THth(suf);			}			break;		case DCH_RM:			if (is_to_char)			{				if (!tm->tm_mon)					return -1;				sprintf(inout, "%*s", S_FM(suf) ? 0 : -4,						rm_months_upper[12 - tm->tm_mon]);				return strlen(p_inout);			}			else			{				tmfc->mm = 12 - seq_search(inout, rm_months_upper, ALL_UPPER, FULL_SIZ, &len);				CHECK_SEQ_SEARCH(len, "RM");				if (S_FM(suf))					return len;				else					return 4;			}			break;		case DCH_rm:			if (is_to_char)			{				if (!tm->tm_mon)					return -1;				sprintf(inout, "%*s", S_FM(suf) ? 0 : -4,						rm_months_lower[12 - tm->tm_mon]);				return strlen(p_inout);			}			else			{				tmfc->mm = 12 - seq_search(inout, rm_months_lower, ALL_LOWER, FULL_SIZ, &len);				CHECK_SEQ_SEARCH(len, "rm");				if (S_FM(suf))					return len;				else					return 4;			}			break;		case DCH_W:			if (is_to_char)			{				sprintf(inout, "%d", (tm->tm_mday - 1) / 7 + 1);				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				sscanf(inout, "%1d", &tmfc->w);				return 1 + SKIP_THth(suf);			}			break;		case DCH_J:			if (is_to_char)			{				sprintf(inout, "%d", date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));				if (S_THth(suf))					str_numth(p_inout, inout, S_TH_TYPE(suf));				return strlen(p_inout);			}			else			{				sscanf(inout, "%d", &tmfc->j);				return strdigits_len(inout) + SKIP_THth(suf);			}			break;	}	return -1;}static DCHCacheEntry *DCH_cache_getnew(char *str){	DCHCacheEntry *ent = NULL;	/* counter overload check  - paranoia? */	if (DCHCounter + DCH_CACHE_FIELDS >= MAX_INT32)	{		DCHCounter = 0;		for (ent = DCHCache; ent <= (DCHCache + DCH_CACHE_FIELDS); ent++)			ent->age = (++DCHCounter);	}	/*	 * Cache is full - needs remove any older entry	 */	if (n_DCHCache > DCH_CACHE_FIELDS)	{		DCHCacheEntry *old = DCHCache + 0;#ifdef DEBUG_TO_FROM_CHAR		elog(DEBUG_elog_output, "cache is full (%d)", n_DCHCache);#endif		for (ent = DCHCache; ent <= (DCHCache + DCH_CACHE_FIELDS); ent++)		{			if (ent->age < old->age)				old = ent;		}#ifdef DEBUG_TO_FROM_CHAR		elog(DEBUG_elog_output, "OLD: '%s' AGE: %d", old->str, old->age);#endif		StrNCpy(old->str, str, DCH_CACHE_SIZE + 1);		/* old->format fill parser */		old->age = (++DCHCounter);		return old;	}	else	{#ifdef DEBUG_TO_FROM_CHAR		elog(DEBUG_elog_output, "NEW (%d)", n_DCHCache);#endif		ent = DCHCache + n_DCHCache;		StrNCpy(ent->str, str, DCH_CACHE_SIZE + 1);		/* ent->format fill parser */		ent->age = (++DCHCounter);		++n_DCHCache;		return ent;	}	return NULL;				/* never */}static DCHCacheEntry *DCH_cache_search(char *str){	int			i = 0;	DCHCacheEntry *ent;	/* counter overload check  - paranoia? */	if (DCHCounter + DCH_CACHE_FIELDS >= MAX_INT32)	{		DCHCounter = 0;		for (ent = DCHCache; ent <= (DCHCache + DCH_CACHE_FIELDS); ent++)			ent->age = (++DCHCounter);	}	for (ent = DCHCache; ent <= (DCHCache + DCH_CACHE_FIELDS); ent++)	{		if (i == n_DCHCache)			break;		if (strcmp(ent->str, str) == 0)		{			ent->age = (++DCHCounter);			return ent;		}		i++;	}	return NULL;}static text *datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval){	FormatNode *format;	char	   *fmt_str,			   *result;	bool		incache;	int			fmt_len = VARSIZE(fmt) - VARHDRSZ;	int			reslen;	text	   *res;	/*	 * Convert fmt to C string	 */	fmt_str = (char *) palloc(fmt_len + 1);	memcpy(fmt_str, VARDATA(fmt), fmt_len);	*(fmt_str + fmt_len) = '\0';	/*	 * Allocate workspace for result as C string	 */	result = palloc((fmt_len * DCH_MAX_ITEM_SIZ) + 1);	*result = '\0';	/*	 * Allocate new memory if format picture is bigger than static cache and	 * not use cache (call parser always)	 */	if (fmt_len > DCH_CACHE_SIZE)	{		format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode));		incache = FALSE;		parse_format(format, fmt_str, DCH_keywords,					 DCH_suff, DCH_index, DCH_TYPE, NULL);		(format + fmt_len)->type = NODE_TYPE_END;		/* Paranoia? */	}	else	{		/*		 * Use cache buffers		 */		DCHCacheEntry *ent;		incache = TRUE;		if ((ent = DCH_cache_search(fmt_str)) == NULL)		{			ent = DCH_cache_getnew(fmt_str);			/*			 * Not in the cache, must run parser and save a new format-picture			 * to the cache.			 */			parse_format(ent->format, fmt_str, DCH_keywords,						 DCH_suff, DCH_index, DCH_TYPE, NULL);			(ent->format + fmt_len)->type = NODE_TYPE_END;		/* Paranoia? */#ifdef DEBUG_TO_FROM_CHAR			/* dump_node(ent->format, fmt_len); */			/* dump_index(DCH_keywords, DCH_index);  */#endif		}		format = ent->format;	}	/* The real work is here */	DCH_processor(format, result, true, is_interval, (void *) tmtc);	if (!incache)		pfree(format);	pfree(fmt_str);	/* convert C-string result to TEXT format */	reslen = strlen(result);	res = (text *) palloc(reslen + VARHDRSZ);	memcpy(VARDATA(res), result, reslen);	VARATT_SIZEP(res) = reslen + VARHDRSZ;	pfree(result);	return res;}/**************************************************************************** *				Public routines ***************************************************************************//* ------------------- * TIMESTAMP to_char() * ------------------- */Datumtimestamp_to_char(PG_FUNCTION_ARGS){	Timestamp	dt = PG_GETARG_TIMESTAMP(0);	text	   *fmt = PG_GETARG_TEXT_P(1),			   *res;	TmToChar	tmtc;	struct pg_tm *tm;	int			thisdate;	if ((VARSIZE(fmt) - VARHDRSZ) <= 0 || TIMESTAMP_NOT_FINITE(dt))		PG_RETURN_NULL();	ZERO_tmtc(&tmtc);	tm = tmtcTm(&tmtc);	if (timestamp2tm(dt, NULL, tm, &tmtcFsec(&tmtc), NULL, NULL) != 0)		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("timestamp out of range")));	thisdate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);	tm->tm_wday = (thisdate + 1) % 7;	tm->tm_yday = thisdate - date2j(tm->tm_year, 1, 1) + 1;	if (!(res = datetime_to_char_body(&tmtc, fmt, false)))		PG_RETURN_NULL();	PG_RETURN_TEXT_P(res);}Datumtimestamptz_to_char(PG_FUNCTION_ARGS){	TimestampTz dt = PG_GETARG_TIMESTAMP(0);	text	   *fmt = PG_GETARG_TEXT_P(1),			   *res;	TmToChar	tmtc;	int			tz;	struct pg_tm *tm;	int			thisdate;	if ((VARSIZE(fmt) - VARHDRSZ) <= 0 || TIMESTAMP_NOT_FINITE(dt))		PG_RETURN_NULL();	ZERO_tmtc(&tmtc);	tm = tmtcTm(&tmtc);	if (timestamp2tm(dt, &tz, tm, &tmtcFsec(&tmtc), &tmtcTzn(&tmtc), NULL) != 0)		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("timestamp out of range")));	thisdate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);	tm->tm_wday = (thisdate + 1) % 7;	tm->tm_yday = thisdate - date2j(tm->tm_year, 1, 1) + 1;	if (!(res = datetime_to_char_body(&tmtc, fmt, false)))		PG_RETURN_NULL();	PG_RETURN_TEXT_P(res);}/* ------------------- * INTERVAL to_char() * ------------------- */Datuminterval_to_char(PG_FUNCTION_ARGS){	Interval   *it = PG_GETARG_INTERVAL_P(0);	text	   *fmt = PG_GETARG_TEXT_P(1),			   *res;	TmToChar	tmtc;	struct pg_tm *tm;	if ((VARSIZE(fmt) - VARHDRSZ) <= 0)		PG_RETURN_NULL();	ZERO_tmtc(&tmtc);	tm = tmtcTm(&tmtc);	if (interval2tm(*it, tm, &tmtcFsec(&tmtc)) != 0)		PG_RETURN_NULL();	/* wday is meaningless, yday approximates the total span in days */	tm->tm_yday = (tm->tm_year * MONTHS_PER_YEAR + tm->tm_mon) * DAYS_PER_MONTH + tm->tm_mday;	if (!(res = datetime_to_char_body(&tmtc, fmt, true)))		PG_RETURN_NULL();	PG_RETURN_TEXT_P(res);}/* --------------------- * TO_TIMESTAMP() * * Make Timestamp from date_str which is formatted at argument 'fmt' * ( to_timestamp is reverse to_char() ) * --------------------- */Datum

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -