obconnector-c/include/ob_oralce_format_models.h
2024-06-12 13:51:27 +08:00

244 lines
6.4 KiB
C

/************************************************************************
Copyright (c) 2021 OceanBase.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02111-1301, USA
Part of this code includes code from PHP's mysqlnd extension
(written by Andrey Hristov, Georg Richter and Ulf Wendel), freely
*************************************************************************/
#include "mysql.h"
#include <stdint.h>
#define DATE_PART_CNT 3
#define TIME_PART_CNT 4
#define OTHER_PART_CNT 4
#define DATETIME_PART_CNT (DATE_PART_CNT + TIME_PART_CNT)
#define ORACLE_DATE_PART_CNT (DATE_PART_CNT + TIME_PART_CNT - 1)
#define TOTAL_PART_CNT (DATETIME_PART_CNT + OTHER_PART_CNT)
#define DT_YEAR 0
#define DT_MON 1
#define DT_MDAY 2
#define DT_HOUR 3
#define DT_MIN 4
#define DT_SEC 5
#define DT_USEC 6
#define DT_DATE 7
#define DT_YDAY 8
#define DT_WDAY 9
#define DT_OFFSET_MIN 10
#define OB_MAX_TZ_ABBR_LEN 32
#define OB_MAX_TZ_NAME_LEN 64
//18446744073709551615
#define MAX_UINT64_STR_LEN 20
#define MAX_DIGITS10_STR_SIZE MAX_UINT64_STR_LEN + 3
#define DT_TYPE_DATE (1UL << 0)
#define DT_TYPE_TIME (1UL << 1)
#define DT_WEEK_SUN_BEGIN (1UL << 5) // sunday is the first day of week, otherwise monday.
#define DT_WEEK_ZERO_BEGIN (1UL << 6) // week num will begin with 0, otherwise 1.
#define DT_WEEK_GE_4_BEGIN (1UL << 7) // week which has 4 or more days is week 1, otherwise has
#define DT_TYPE_ORACLE (1UL << 8) //oracle timestamp to nanosecond (nano, tz, ltz)
// the first sunday of monday.
#define DT_TYPE_TIMEZONE (1UL << 10) //oracle timestamp with time zone (tz)
#define DT_TYPE_DATETIME (DT_TYPE_DATE | DT_TYPE_TIME)
#define IS_SUN_BEGIN(mode) ((DT_WEEK_SUN_BEGIN & (mode)) ? 1 : 0)
#define IS_ZERO_BEGIN(mode) ((DT_WEEK_ZERO_BEGIN & (mode)) ? 1 : 0)
#define IS_GE_4_BEGIN(mode) ((DT_WEEK_GE_4_BEGIN & (mode)) ? 1 : 0)
#define HAS_TYPE_ORACLE(mode) ((DT_TYPE_ORACLE & (mode)) ? 1 : 0)
#define HAS_TYPE_TIMEZONE(mode) ((DT_TYPE_TIMEZONE & (mode)) ? 1 : 0)
#define DAYS_PER_WEEK 7
#define MONS_PER_YEAR 12
#define SECS_PER_MIN 60
#define MINS_PER_HOUR 60
typedef uint64_t ObDTMode;
enum ElementFlag
{
INVALID_FLAG = -1,
AD = 0,
AD2, //A.D.
BC,
BC2, //B.C.
CC,
SCC,
D,
DAY,
DD,
DDD,
DY,
FF1,
FF2,
FF3,
FF4,
FF5,
FF6,
FF7,
FF8,
FF9,
FF,
HH,
HH24,
HH12,
IW,
I,
IY,
IYY,
IYYY,
MI,
MM,
MONTH,
MON,
AM,
AM2, //A.M.
PM,
PM2, //P.M.
Q,
RR,
RRRR,
SS,
SSSSS,
WW,
W,
YGYYY,
YEAR,
SYEAR,
YYYY,
SYYYY,
YYY,
YY,
Y,
DS,
DL,
TZH,
TZM,
TZD,
TZR,
X,
J,
///<<< !!!add any flag before this line!!!
MAX_FLAG_NUMBER
};
enum ElementGroup
{
RUNTIME_CONFLICT_SOLVE_GROUP = -2,
NON_CONFLICT_GROUP = -1,
///<<< conflict in group, before this line, will be ignored
NEVER_APPEAR_GROUP = 0, //the element should never appear
YEAR_GROUP, //include : SYYYY YYYY YYY YY Y YGYYY RR RRRR
MERIDIAN_INDICATOR_GROUP, //include : AM PM
WEEK_OF_DAY_GROUP, //include : D Day Dy
ERA_GROUP, //include : AD BC
HOUR_GROUP, //include : HH HH12 HH24
MONTH_GROUP, //include : MONTH MON MM
DAY_OF_YEAR_GROUP, //include : DDD, J
///<<< !!!add any flag before this line!!!
MAX_CONFLICT_GROUP_NUMBER
};
struct ObTimeConstStr {
const char *ptr_;
int32_t len_;
};
struct ObDFMParseCtx
{
const char* fmt_str_;
const char* cur_ch_;
int64_t remain_len_;
//the following values are only used in function str_to_ob_time_oracle_dfm
int64_t expected_elem_flag_;
my_bool is_matching_by_expected_len_; //only used for match_int_value
};
enum UpperCaseMode {
NON_CHARACTER,
ONLY_FIRST_CHARACTER,
ALL_CHARACTER
};
struct ObDFMElem
{
int64_t elem_flag_; //flag from enum ObDFMFlag
int64_t offset_; //offset in origin format string
my_bool is_single_dot_before_; //for the dot before FF
enum UpperCaseMode upper_case_mode_;
};
struct ObTime
{
uint64_t mode_;
int32_t parts_[TOTAL_PART_CNT];
// year: [1000, 9999].
// month: [1, 12].
// day: [1, 31].
// hour: [0, 23] or [0, 838] if it is a time.
// minute: [0, 59].
// second: [0, 59].
// usecond: [0, 1000000], 1000000 can only valid after str_to_ob_time, for round.
// nanosecond: [0, 1000000000], when HAS_TYPE_ORACLE(mode_)
// date: date value, day count since 1970-1-1.
// year day: [1, 366].
// week day: [1, 7], 1 means monday, 7 means sunday.
// offset minute: [-12*60, 14*60].
char tz_name_[OB_MAX_TZ_NAME_LEN];
char tzd_abbr_[OB_MAX_TZ_ABBR_LEN];//the abbr of time zone region with Daylight Saving Time
int32_t time_zone_id_;
uint8_t nano_scale_;
my_bool is_tz_name_valid_;
};
struct ObFastFormatInt
{
char buf_[MAX_DIGITS10_STR_SIZE];
char *ptr_;
int64_t len_;
};
struct ObOracleTimeLimiter
{
int32_t MIN;
int32_t MAX;
int ERROR_CODE;
};
longlong strtoll10(const char *nptr, char **endptr, int *error);
int calculate_str_oracle_dfm_length(const struct ObTime *ob_time,
const char *fmt_str, const int64_t fmt_len,
int16_t scale, int64_t *len);
int ob_time_to_str_oracle_dfm(const struct ObTime *ob_time,
const char *fmt_str, const int64_t fmt_len,
int16_t scale,
char *buf, int64_t buf_len,
int64_t *pos);
int32_t ob_time_to_date(struct ObTime *ob_time);
int str_to_ob_time_oracle_dfm(const char *str, const int64_t str_len,
const char *fmt_str, const int64_t fmt_len,
struct ObTime *ob_time,
int16_t scale);