Skip to content

Commit

Permalink
Support TIMESTAMP
Browse files Browse the repository at this point in the history
  • Loading branch information
jcwangxp committed Nov 1, 2024
1 parent f25e2b8 commit 153f400
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ It is designed for high-performance scenarios where the main memory can hold the
- Supports multi-column indexes.
- Supports exact match, leftmost match (TBD), and range match (TBD).
- Supports standard ACID transactions.
- Supports WAL for OnDisk storage (TBD).
- Supports WAL for OnDisk storage.
- Supports multiple threads and multiple processes access.
- Supports table-level read-write locks.
- Supports Reader-Writer MVCC (write transaction doesn't block read transactions).
Expand Down
1 change: 1 addition & 0 deletions src/admin/xdb_backup.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ xdb_res2sql (FILE *pFile, xdb_res_t *pRes, const char *tbl_name, char *buf, int
len += sprintf (buf+len, "%d,", *(int16_t*)pVal);
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
len += sprintf (buf+len, "%"PRIi64",", *(int64_t*)pVal);
break;
case XDB_TYPE_FLOAT:
Expand Down
38 changes: 38 additions & 0 deletions src/admin/xdb_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,26 @@ xdb_get_row_len (xdb_meta_t *pMeta, xdb_row_t *pRow, int *pColLen)
case XDB_TYPE_VBINARY:
pColLen[i] = 2 + *(uint16_t*)(pVal-2) * 2;
break;
case XDB_TYPE_TIMESTAMP:
{
struct tm tm_val;
int millsec = *(int64_t*)pVal%1000000;
time_t time_val = (time_t)*(int64_t*)pVal/1000000;
char buf[32];
localtime_r(&time_val, &tm_val);
int len = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tm_val);
if (millsec) {
if (millsec%1000) {
len += sprintf (buf+len, ".%06d", millsec);
} else {
len += sprintf (buf+len, ".%03d", millsec/1000);
}
}
if (pColLen[i] < len) {
pColLen[i] = len;
}
}
break;
}
}
}
Expand Down Expand Up @@ -253,6 +273,24 @@ xdb_fprint_row_table (FILE *pFile, xdb_meta_t *pMeta, xdb_row_t *pRow, int *pCol
}
}
break;
case XDB_TYPE_TIMESTAMP:
{
struct tm tm_val;
int millsec = *(int64_t*)pVal%1000000;
time_t time_val = (time_t)*(int64_t*)pVal/1000000;
char buf[32];
localtime_r(&time_val, &tm_val);
int len = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tm_val);
if (millsec) {
if (millsec%1000) {
len += sprintf (buf+len, ".%06d", millsec);
} else {
len += sprintf (buf+len, ".%03d", millsec/1000);
}
}
plen = fprintf (pFile, "%s", buf);
}
break;
}
}

Expand Down
66 changes: 66 additions & 0 deletions src/core/xdb_crud.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ xdb_row_isequal (xdb_tblm_t *pTblm, void *pRow, xdb_field_t **ppFields, xdb_valu
}
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
if (pValue->ival != *(int64_t*)pFldVal) {
return false;
}
Expand Down Expand Up @@ -314,6 +315,7 @@ xdb_row_isequal2 (xdb_tblm_t *pTblm, void *pRowL, void *pRowR, xdb_field_t **ppF
}
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
if (*(int64_t*)pFldValL != *(int64_t*)pFldValR) {
return false;
}
Expand Down Expand Up @@ -405,6 +407,7 @@ xdb_row_cmp (const void *pRowL, const void *pRowR, const xdb_field_t **ppFields,
}
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
cmp = *(int64_t*)pRowValL - *(int64_t*)pRowValR;
if (cmp) {
*pCount = i;
Expand Down Expand Up @@ -481,6 +484,7 @@ xdb_row_and_match (xdb_tblm_t *pTblm, void *pRow, xdb_filter_t **pFilters, int c
value.val_type = XDB_TYPE_BIGINT;
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
value.ival = *(int64_t*)pVal;
value.val_type = XDB_TYPE_BIGINT;
break;
Expand Down Expand Up @@ -661,6 +665,7 @@ xdb_row_getval (void *pRow, xdb_value_t *pVal)
pVal->sup_type = XDB_TYPE_BIGINT;
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
pVal->ival = *(int64_t*)pFldPtr;
pVal->sup_type = XDB_TYPE_BIGINT;
break;
Expand Down Expand Up @@ -797,6 +802,7 @@ xdb_col_set2 (void *pColPtr, xdb_type_t col_type, xdb_value_t *pVal)
*(int32_t*)(pColPtr) = pVal->ival;
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
*(int64_t*)(pColPtr) = pVal->ival;
break;
case XDB_TYPE_BOOL:
Expand Down Expand Up @@ -831,6 +837,7 @@ xdb_col_set (xdb_tblm_t *pTblm, void *pRow, xdb_field_t *pField, xdb_value_t *pV
*(int32_t*)(pColPtr) = pVal->ival;
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
*(int64_t*)(pColPtr) = pVal->ival;
break;
case XDB_TYPE_BOOL:
Expand Down Expand Up @@ -899,6 +906,7 @@ xdb_row_hash (xdb_tblm_t *pTblm, void *pRow, xdb_field_t *pFields[], int count)
hash = *(int32_t*)ptr;
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
hash = *(int64_t*)ptr;
break;
case XDB_TYPE_BOOL:
Expand Down Expand Up @@ -965,6 +973,7 @@ xdb_row_hash2 (xdb_tblm_t *pTblm, void *pRow, xdb_field_t *pFields[], int count)
hash = *(int32_t*)ptr;
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
hash = *(int64_t*)ptr;
break;
case XDB_TYPE_BOOL:
Expand Down Expand Up @@ -1096,6 +1105,7 @@ xdb_row_getInt (uint64_t meta, void *pRow, uint16_t iCol)
case XDB_TYPE_INT:
return *(int32_t*)pVal;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
return *(int64_t*)pVal;
case XDB_TYPE_BOOL:
case XDB_TYPE_TINYINT:
Expand All @@ -1115,6 +1125,7 @@ xdb_fld_setInt (void *pAddr, xdb_type_t type, int64_t val)
*(int32_t*)pAddr = val;
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
*(int64_t*)pAddr = val;
break;
case XDB_TYPE_BOOL:
Expand Down Expand Up @@ -1287,6 +1298,7 @@ int64_t xdb_column_int64 (uint64_t meta, xdb_row_t *pRow, uint16_t iCol)
case XDB_TYPE_INT:
return *(int32_t*)pRow[iCol];
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
return *(int64_t*)pRow[iCol];
case XDB_TYPE_BOOL:
case XDB_TYPE_TINYINT:
Expand Down Expand Up @@ -1419,6 +1431,24 @@ int xdb_fprint_row (FILE *pFile, uint64_t meta, xdb_row_t *pRow, int format)
}
fprintf (pFile, "' ");
break;
case XDB_TYPE_TIMESTAMP:
{
struct tm tm_val;
int millsec = *(int64_t*)pVal%1000000;
time_t time_val = (time_t)*(int64_t*)pVal/1000000;
char buf[32];
localtime_r(&time_val, &tm_val);
int len = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tm_val);
if (millsec) {
if (millsec%1000) {
len += sprintf (buf+len, ".%06d", millsec);
} else {
len += sprintf (buf+len, ".%03d", millsec/1000);
}
}
fprintf (pFile, "%s='%s' ", pCol[i]->col_name, buf);
}
break;
}
}
return 0;
Expand Down Expand Up @@ -1454,6 +1484,24 @@ int xdb_fprint_dbrow (FILE *pFile, xdb_tblm_t *pTblm, void *pDbRow, int format)
case XDB_TYPE_BIGINT:
fprintf (pFile, "%s=%"PRIi64" ", XDB_OBJ_NAME(pField), *(int64_t*)pVal);
break;
case XDB_TYPE_TIMESTAMP:
{
struct tm tm_val;
int millsec = *(int64_t*)pVal%1000000;
time_t time_val = (time_t)*(int64_t*)pVal/1000000;
char buf[32];
localtime_r(&time_val, &tm_val);
int len = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tm_val);
if (millsec) {
if (millsec%1000) {
len += sprintf (buf+len, ".%06d", millsec);
} else {
len += sprintf (buf+len, ".%03d", millsec/1000);
}
}
fprintf (pFile, "%s='%s' ", XDB_OBJ_NAME(pField), buf);
}
break;
case XDB_TYPE_FLOAT:
fprintf (pFile, "%s=%f ", XDB_OBJ_NAME(pField), *(float*)pVal);
break;
Expand Down Expand Up @@ -2204,6 +2252,24 @@ xdb_sprint_field (xdb_field_t *pField, void *pRow, char *buf)
}
*(buf + len++) = '\'';
break;
case XDB_TYPE_TIMESTAMP:
{
struct tm tm_val;
int millsec = *(int64_t*)pVal%1000000;
time_t time_val = (time_t)*(int64_t*)pVal/1000000;
localtime_r(&time_val, &tm_val);
*(buf + len++) = '\'';
len += strftime(buf+len, 32, "%Y-%m-%dT%H:%M:%S", &tm_val);
if (millsec) {
if (millsec%1000) {
len += sprintf (buf+len, ".%06d", millsec);
} else {
len += sprintf (buf+len, ".%03d", millsec/1000);
}
}
*(buf + len++) = '\'';
}
break;
}

return len;
Expand Down
26 changes: 6 additions & 20 deletions src/core/xdb_sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,18 +692,11 @@ xdb_stmt_vbexec2 (xdb_stmt_t *pStmt, va_list ap)
case XDB_TYPE_INT:
case XDB_TYPE_SMALLINT:
case XDB_TYPE_TINYINT:
pVal->ival = va_arg (ap, int);
break;
case XDB_TYPE_BOOL:
str = va_arg (ap, char *);
if (!strcasecmp(str, "true")) {
pVal->ival = 1;
} else {
XDB_EXPECT (!strcasecmp(str, "false"), XDB_E_STMT, "Expect TRUE/FALSE");
pVal->ival = 0;
}
pVal->ival = va_arg (ap, int);
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
pVal->ival = va_arg (ap, int64_t);
break;
case XDB_TYPE_FLOAT:
Expand Down Expand Up @@ -741,18 +734,11 @@ xdb_stmt_vbexec2 (xdb_stmt_t *pStmt, va_list ap)
*(int16_t*)pAddr = va_arg (ap, int);
break;
case XDB_TYPE_TINYINT:
*(int8_t*)pAddr = va_arg (ap, int);
break;
case XDB_TYPE_BOOL:
str = va_arg (ap, char *);
if (!strcasecmp(str, "true")) {
*(int8_t*)pAddr = 1;
} else {
XDB_EXPECT (!strcasecmp(str, "false"), XDB_E_STMT, "Expect TRUE/FALSE");
*(int8_t*)pAddr = 0;
}
*(int8_t*)pAddr = va_arg (ap, int);
break;
case XDB_TYPE_BIGINT:
case XDB_TYPE_TIMESTAMP:
*(int64_t*)pAddr = va_arg (ap, int64_t);
break;
case XDB_TYPE_FLOAT:
Expand Down Expand Up @@ -818,8 +804,8 @@ xdb_stmt_vbexec2 (xdb_stmt_t *pStmt, va_list ap)

return xdb_stmt_exec (pStmt);

error:
return &pConn->conn_res;
//error:
// return &pConn->conn_res;
}

xdb_res_t*
Expand Down
2 changes: 1 addition & 1 deletion src/core/xdb_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ xdb_create_table (xdb_stmt_tbl_t *pStmt)
pTblm->row_size = pStmt->row_size;
if (pStmt->row_size < 1) {
pTblm->row_size = 0;
xdb_alloc_offset (pTblm, (1LL<<XDB_TYPE_BIGINT) | (1LL<<XDB_TYPE_DOUBLE), 8);
xdb_alloc_offset (pTblm, (1LL<<XDB_TYPE_BIGINT) | (1LL<<XDB_TYPE_DOUBLE)| (1LL<<XDB_TYPE_TIMESTAMP), 8);
xdb_alloc_offset (pTblm, (1LL<<XDB_TYPE_INT) | (1LL<<XDB_TYPE_FLOAT), 4);
xdb_alloc_offset (pTblm, (1LL<<XDB_TYPE_VCHAR) | (1LL<<XDB_TYPE_VBINARY), 4);
xdb_alloc_offset (pTblm, (1LL<<XDB_TYPE_CHAR) | (1LL<<XDB_TYPE_BINARY) | (1LL<<XDB_TYPE_SMALLINT), 2);
Expand Down
54 changes: 54 additions & 0 deletions src/parser/xdb_parser_dml.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,47 @@ XDB_STATIC xdb_field_t * xdb_stmt_find_field (xdb_conn_t *pConn, xdb_stmt_select
}
#endif

XDB_STATIC int64_t
xdb_timestamp_scanf (const char *time_str)
{
struct tm tm;
uint32_t n, mm = 0, dd = 0, yy = 0, HH = 0, MM = 0, SS = 0, SubSec = 0;
uint64_t time_val;
char pad[6];

n = sscanf(time_str, "%u%c%u%c%u%c%u%c%u%c%u%c%u", &yy, &pad[0], &mm, &pad[1], &dd, &pad[2], &HH, &pad[3], &MM, &pad[4], &SS, &pad[4], &SubSec);

if (1 == n) {
return yy;
}

tm.tm_mon = mm - 1;
tm.tm_mday = dd;
tm.tm_year = yy - 1900;

tm.tm_hour = HH;
tm.tm_min = MM;
tm.tm_sec = SS;
tm.tm_isdst = -1; // Daylight saving time auto set by system

time_val = mktime(&tm);

if (SubSec > 0) {
char *dot = strrchr (time_str, '.');
if (dot) {
switch (strlen(dot)-1) {
case 1: SubSec *= 100000; break;
case 2: SubSec *= 10000; break;
case 3: SubSec *= 1000; break;
case 4: SubSec *= 100; break;
case 5: SubSec *= 10; break;
}
}
}

return time_val*1000000 + SubSec;
}

XDB_STATIC xdb_stmt_t*
xdb_parse_insert (xdb_conn_t* pConn, xdb_token_t *pTkn, bool bPStmt)
{
Expand Down Expand Up @@ -180,6 +221,12 @@ xdb_parse_insert (xdb_conn_t* pConn, xdb_token_t *pTkn, bool bPStmt)
*(int32_t*)(pRow+pField->fld_off) = atoi (pTkn->token);
//xdb_dbgprint ("%s %d\n", pField->fld_name, vi32);
break;
case XDB_TYPE_TIMESTAMP:
if (XDB_TOK_STR == type) {
*(int64_t*)(pRow+pField->fld_off) = xdb_timestamp_scanf (pTkn->token);
break;
}
// fall through
case XDB_TYPE_BIGINT:
XDB_EXPECT ((XDB_TOK_NUM == type), XDB_E_STMT, "Expect number");
*(int64_t*)(pRow+pField->fld_off) = atoll (pTkn->token);
Expand Down Expand Up @@ -573,6 +620,13 @@ xdb_parse_where (xdb_conn_t* pConn, xdb_stmt_select_t *pStmt, xdb_token_t *pTkn)
pStmt->pBind[pStmt->bind_count++] = &pFilter->val;
} else {
switch (pField->fld_type) {
case XDB_TYPE_TIMESTAMP:
if (XDB_TOK_STR == vtype) {
pFilter->val.ival = xdb_timestamp_scanf (pVal);
pFilter->val.val_type = XDB_TYPE_BIGINT;
break;
}
// fall through
case XDB_TYPE_INT:
case XDB_TYPE_BIGINT:
case XDB_TYPE_TINYINT:
Expand Down
3 changes: 3 additions & 0 deletions src/parser/xdb_parser_tbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ xdb_parse_field (xdb_conn_t* pConn, xdb_token_t *pTkn, xdb_stmt_tbl_t *pStmt)
} else if (0 == strcasecmp (pTkn->token, "BIGINT")) {
pFld->fld_type = XDB_TYPE_BIGINT;
pFld->sup_type = XDB_TYPE_BIGINT;
} else if (0 == strcasecmp (pTkn->token, "TIMESTAMP")) {
pFld->fld_type = XDB_TYPE_TIMESTAMP;
pFld->sup_type = XDB_TYPE_BIGINT;
} else if (0 == strcasecmp (pTkn->token, "FLOAT")) {
pFld->fld_type = XDB_TYPE_FLOAT;
pFld->sup_type = XDB_TYPE_DOUBLE;
Expand Down

0 comments on commit 153f400

Please sign in to comment.