check in lex/yacc based relational algebra primitives

This commit is contained in:
Sears Russell 2008-09-28 06:39:45 +00:00
parent ff0887624c
commit e96b4d1c05
20 changed files with 2132 additions and 561 deletions

View file

@ -3,12 +3,19 @@ Project(Stasis)
SET(PACKAGE_VERSION 1)
SUBDIRS(src test utilities benchmarks examples)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
SET(FLEX_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
SET(BISON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Main decisions
SET(BUILD_SHARED_LIBS ON)
#ENABLE_TESTING()
INCLUDE(CTest)
FIND_PACKAGE(FLEX)
FIND_PACKAGE(BISON)
# Look for include files
INCLUDE (CheckIncludeFiles)
FIND_LIBRARY(CHECK_LIBRARY NAMES check)

View file

@ -1,5 +1,6 @@
ADD_LIBRARY(referential algebra.c dml.c)
SET(COMMON_LIBRARIES referential ${COMMON_LIBRARIES})
SUBDIRS(lang)
ADD_LIBRARY(referential algebra.c dml.c ddl.c tuple.c lang/ast.c)
SET(COMMON_LIBRARIES referential refparse ${COMMON_LIBRARIES})
IF(CHECK_LIBRARY)
CREATE_CHECK_OPT(toplevel ${CMAKE_CURRENT_SOURCE_DIR}/test-script.ref)
ENDIF(CHECK_LIBRARY)

File diff suppressed because it is too large Load diff

View file

@ -1,19 +1,29 @@
#ifndef __ALGEBRA_H
#define __ALGEBRA_H
#include "lang/ast.h"
typedef struct {
recordid hash;
} ReferentialAlgebra_context_t;
lladdIterator_t* ReferentialAlgebra_ExecuteQuery(int xid,
ReferentialAlgebra_context_t* c, union_qry *q);
lladdIterator_t* ReferentialAlgebra_OpenTableScanner(int xid, recordid catalog,
char * tablename);
lladdIterator_t* ReferentialAlgebra_Select(int xid, lladdIterator_t* it,
char ** predicate);
union_cmp * predicate);
lladdIterator_t* ReferentialAlgebra_Project(int xid, lladdIterator_t * it,
char ** project);
col_tuple * project);
lladdIterator_t* ReferentialAlgebra_Join(int xid,
lladdIterator_t * outer_it,
lladdIterator_t * inner_it,
cmp_tuple * cmp);
lladdIterator_t* ReferentialAlgebra_KeyValCat(int xid, lladdIterator_t * it);
char * tplRid(recordid rid);
recordid ridTpl(char * tpl);
void ReferentialAlgebra_init();
char ** executeQuery(int xid, recordid hash, char * line);
lladdIterator_t * parseExpression(int xid, recordid catalog, char **head);
char** parseTuple(char ** head);
ReferentialAlgebra_context_t * ReferentialAlgebra_openContext(int xid, recordid rid);
recordid ReferentialAlgebra_allocContext(int xid);
#endif

View file

@ -0,0 +1,20 @@
#include "ddl.h"
#include <stdlib.h>
#include <string.h>
int ReferentialDDL_CreateTable(int xid, ReferentialAlgebra_context_t*context, create *q) {
recordid newTable = ThashCreate(xid, VARIABLE_LENGTH, VARIABLE_LENGTH); // XXX assumes first col is a string!
tuple_t ridtpl = tupleRid(newTable);
tuple_t union_typ_tup = tupleUnion_typ(q->schema);
assert(union_typ_tup.count);
assert(union_typ_tup.col[0].int64 == string_typ); // XXX
ridtpl = tupleCatTuple(ridtpl,union_typ_tup);
tupleFree(union_typ_tup);
size_t tplLen;
byte * tplBytes = byteTuple(ridtpl,&tplLen);
ThashInsert(xid,context->hash,(byte*)q->tbl,strlen(q->tbl)+1,tplBytes,tplLen);
free(tplBytes);
return 1;
}

View file

@ -0,0 +1,6 @@
#ifndef DDL_H
#define DDL_H
#include "algebra.h"
#include "lang/ast.h"
int ReferentialDDL_CreateTable(int xid, ReferentialAlgebra_context_t*context, create *q);
#endif //DDL_H

View file

@ -1,9 +1,13 @@
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stasis/transactional.h>
#include "dml.h"
#include "algebra.h"
/*
int executeInsert(int xid, recordid tables, char * insert) {
char * linecopy = strdup(insert+strlen("insert"));
char * strtoks;
@ -61,3 +65,89 @@ int executeDelete(int xid, recordid tables, char * delete) {
free(linecopy);
return 1;
}
*/
static recordid ReferentialDML_lookupTableRid(int xid, ReferentialAlgebra_context_t*context, char * tablename) {
expr_list * results = 0;
char * line;
asprintf(&line, "query {p ($1,$2,$3) {s ($0=\"%s\") TABLES} }", tablename);
//XXX memory leak!
parse(line,&results);
assert(results); //XXX
assert(results->count == 1); //XXX
lladdIterator_t * it = ReferentialAlgebra_ExecuteQuery(xid, context, results->ents[0]->u.q);
recordid tableRid;
if(it) {
int first = 1;
while(Titerator_next(xid,it)) {
assert(first);
first = 0;
byte * tup;
Titerator_value(xid, it, &tup);
tableRid = ridTuple(*(tuple_t*)tup);
}
Titerator_close(xid, it);
} else {
abort(); //XXX
}
return tableRid;
}
int ReferentialDML_InsertTuple(int xid, ReferentialAlgebra_context_t*context, char * tablename, tuple_t t) {
//XXX assumes table format is key value, starting with a string.
tuple_t val = tupleTail(t, 1);
size_t val_len;
byte * val_byte = byteTuple(val,&val_len);
recordid tableRid = ReferentialDML_lookupTableRid(xid,context,tablename);
if(t.type[0] == string_typ) {
ThashInsert(xid, tableRid, (byte*)t.col[0].string, 1+strlen(t.col[0].string), val_byte, val_len);
} else if(t.type[0] == int64_typ) {
abort(); // int keys not supported yet
ThashInsert(xid, tableRid, (byte*)&t.col[0].int64, sizeof(int64_t), val_byte, val_len);
} else {
abort();
}
free(val_byte);
tupleFree(val);
return 0;
}
int ReferentialDML_DeleteTuple(int xid, ReferentialAlgebra_context_t*context, char * tablename, tuple_t t) {
//XXX assumes table format is key value, starting with a string.
// tuple_t val = tupleTail(t, 1);
// size_t val_len;
// byte * val_byte = byteTuple(val,&val_len);
recordid tableRid = ReferentialDML_lookupTableRid(xid,context,tablename);
if(t.type[0] == string_typ) {
ThashRemove(xid, tableRid, (byte*)t.col[0].string, 1+strlen(t.col[0].string)); //, val_byte, val_len);
} else if(t.type[0] == int64_typ) {
abort(); // int keys not supported yet
ThashRemove(xid, tableRid, (byte*)&t.col[0].int64, sizeof(int64_t)); //, val_byte, val_len);
} else {
abort();
}
//free(val_byte);
//tupleFree(val);
return 0;
}
int ReferentialDML_ExecuteInsert(int xid, ReferentialAlgebra_context_t*context, insert *i) {
tuple_t t = tupleVal_tuple(i->t);
int ret = ReferentialDML_InsertTuple(xid, context, i->tbl, t);
tupleFree(t);
return ret;
}
int ReferentialDML_ExecuteDelete(int xid, ReferentialAlgebra_context_t*context, delete *d) {
tuple_t t = tupleVal_tuple(d->t);
int ret = ReferentialDML_DeleteTuple(xid, context, d->tbl, t);
tupleFree(t);
return ret;
}

View file

@ -1,4 +1,6 @@
#include <stasis/transactional.h>
#include "algebra.h"
#include "lang/ast.h"
int executeDelete(int xid, recordid tables, char * delete);
int executeInsert(int xid, recordid tables, char *insert);
int ReferentialDML_ExecuteInsert(int xid, ReferentialAlgebra_context_t*context, insert *i);
int ReferentialDML_ExecuteDelete(int xid, ReferentialAlgebra_context_t*context, delete *i);

View file

@ -0,0 +1,10 @@
BISON_TARGET(RefParser ${CMAKE_CURRENT_SOURCE_DIR}/parse.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c)
FLEX_TARGET(RefParser ${CMAKE_CURRENT_SOURCE_DIR}/lexer.lex ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c)
#SET(INCLUDE_DIR ${INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
#COPY_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ast.h ${CMAKE_CURRENT_BINARY_DIR}/ast.h)
ADD_LIBRARY(refparse ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c ${CMAKE_CURRENT_SOURCE_DIR}/ast.c)
ADD_EXECUTABLE(parser ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c ${CMAKE_CURRENT_SOURCE_DIR}/ast.c ${CMAKE_CURRENT_SOURCE_DIR}/parse.c)
SET_TARGET_PROPERTIES(refparse PROPERTIES COMPILE_FLAGS "-Wno-implicit -Wno-unused -I ${CMAKE_CURRENT_SOURCE_DIR}")
SET_TARGET_PROPERTIES(parser PROPERTIES COMPILE_FLAGS "-Wno-implicit -Wno-unused -I ${CMAKE_CURRENT_SOURCE_DIR}")
ADD_TEST(test_parser ${CMAKE_CURRENT_SOURCE_DIR}/test_parser.pl)

View file

@ -0,0 +1,368 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ast.h"
/*
int walk(const expr_list * el) {
return walk_expr_list(el);
}
#define WALK_LIST(type, child_type) \
int walk_##type(const type * x) { \
int ret = 0; \
for(int i = 0; i < x->count; i++) { \
ret |= walk_##child_type(x->ents[i]); \
} \
return ret; \
}
#define WALK_LIST_DECL(type) \
int walk_##type(const type * x);
#define WALK_LEAF(type) \
int walk_##type(const type * x) { \
return 0; \
}
#define WALK_LEAF_DECL(type) \
int walk_##type(const type * x);
WALK_LIST_DECL(expr_list)
WALK_LEAF_DECL(expr)
WALK_LIST(expr_list, expr)
WALK_LEAF(expr)
*/
char * astrncat(char * dest, const char * src) {
size_t destlen = dest ? strlen(dest) : 0;
size_t srclen = strlen(src);
dest = realloc(dest, destlen+srclen+1);
if(srclen && !destlen) { dest[0] = 0; }
/* printf("src =>%s<=",src); */
strcat(dest, src);
return dest;
}
char * afstrncat(char *dest, char * src) {
dest = astrncat(dest, src);
free(src);
return dest;
}
char * pp_expr_list(const expr_list* el) {
char * ret = 0;
int i;
for(i = 0; i < el->count; i++) {
ret = afstrncat(ret, pp_expr(el->ents[i]));
ret = astrncat(ret, "\n");
}
return ret;
}
char * pp_expr(const expr* e) {
char * ret = 0;
switch(e->typ) {
case query_typ: {
ret = astrncat(ret, "query ");
ret = afstrncat(ret, pp_union_qry(e->u.q));
} break;
case insert_typ: {
ret = astrncat(ret, "insert ");
ret = afstrncat(ret, pp_insert(e->u.i));
} break;
case delete_typ: {
ret = astrncat(ret, "delete ");
ret = afstrncat(ret, pp_delete(e->u.d));
} break;
case create_typ: {
ret = astrncat(ret, "create ");
ret = afstrncat(ret, pp_create(e->u.c));
} break;
default: abort();
}
return ret;
}
char * pp_query(const query* q) {
char * ret = 0;
switch(q->typ) {
case scan_typ: {
ret = afstrncat(ret, pp_q_scan(q->u.scn));
} break;
case table_star_typ: {
ret = astrncat(ret, "*");
} break;
case select_typ: {
ret = astrncat(ret, "{s ");
ret = afstrncat(ret, pp_union_cmp(q->u.sel->t));
ret = astrncat(ret, " ");
ret = afstrncat(ret, pp_union_qry(q->u.sel->q));
ret = astrncat(ret, "}");
} break;
case project_typ: {
ret = astrncat(ret, "{p ");
ret = afstrncat(ret, pp_col_tuple(q->u.prj->t));
ret = astrncat(ret, " ");
ret = afstrncat(ret, pp_union_qry(q->u.prj->q));
ret = astrncat(ret, "}");
} break;
case join_typ: {
ret = astrncat(ret, "{j ");
ret = afstrncat(ret, pp_cmp_tuple(q->u.jn->t));
ret = astrncat(ret, " ");
ret = afstrncat(ret, pp_union_qry(q->u.jn->lhs));
ret = astrncat(ret, " ");
ret = afstrncat(ret, pp_union_qry(q->u.jn->rhs));
ret = astrncat(ret, "}");
} break;
default: abort();
}
return ret;
}
char * pp_create(const create * c){
char * ret = 0;
ret = astrncat(ret, c->tbl);
ret = astrncat(ret, " ");
ret = astrncat(ret, pp_union_typ(c->schema));
return ret;
}
char * pp_q_scan(const q_scan* s) {
char * ret = 0;
asprintf(&ret, "%s", s->table);
return ret;
}
char * pp_insert(const insert * i) {
char * ret = 0;
asprintf(&ret, "%s ", i->tbl);
ret = afstrncat(ret, pp_val_tuple(i->t));
return ret;
}
char * pp_delete(const delete * d) {
char * ret = 0;
asprintf(&ret, "%s ", d->tbl);
ret = afstrncat(ret, pp_val_tuple(d->t));
return ret;
}
/*char * pp_pat_tuple(const pat_tuple * p) {
int i;
char * ret = 0;
int first = 1;
ret = astrncat(ret,"(");
for(i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,", ");
} else {
first = 0;
}
ret = afstrncat(ret, pp_pat_entry(p->ents[i]));
}
ret = astrncat(ret,")");
return ret;
} */
char * pp_val_tuple(const val_tuple * p) {
int i;
char * ret = 0;
int first = 1;
ret = astrncat(ret,"(");
for(i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,", ");
} else {
first = 0;
}
ret = afstrncat(ret, pp_val_entry(p->ents[i]));
}
ret = astrncat(ret,")");
return ret;
}
char * pp_col_tuple(const col_tuple * p) {
int i;
char * ret = 0;
int first = 1;
ret = astrncat(ret,"(");
for(i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,", ");
} else {
first = 0;
}
ret = afstrncat(ret, pp_col_entry(p->ents[i]));
}
ret = astrncat(ret,")");
return ret;
}
char * pp_cmp_tuple(const cmp_tuple * p) {
int i;
char * ret = 0;
int first = 1;
ret = astrncat(ret,"(");
for(i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,", ");
} else {
first = 0;
}
ret = afstrncat(ret, pp_cmp_entry(p->ents[i]));
}
ret = astrncat(ret,")");
return ret;
}
char * pp_typ_tuple(const typ_tuple * p) {
int i;
char * ret = 0;
int first = 1;
ret = astrncat(ret,"(");
for(i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,", ");
} else {
first = 0;
}
ret = afstrncat(ret, pp_typ_entry(p->ents[i]));
}
ret = astrncat(ret,")");
return ret;
}
char * pp_union_qry(const union_qry * p) {
char * ret = 0;
int first = 1;
for(int i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,"|");
} else {
first = 0;
}
ret = astrncat(ret, pp_query(p->ents[i]));
}
return ret;
}
char * pp_union_typ(const union_typ * p) {
char * ret = 0;
int first = 1;
for(int i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,"|");
} else {
first = 0;
}
ret = astrncat(ret, pp_typ_tuple(p->ents[i]));
}
return ret;
}
char * pp_union_cmp(const union_cmp * p) {
char * ret = 0;
int first = 1;
for(int i = 0; i < p->count; i++) {
if(!first) {
ret = astrncat(ret,"|");
} else {
first = 0;
}
ret = astrncat(ret, pp_cmp_tuple(p->ents[i]));
}
return ret;
}
/*char * pp_pat_entry(const pat_entry * p) {
char * ret = 0;
switch(p->typ) {
case star_typ: {
asprintf(&ret,"*");
} break;
case ident_typ: {
asprintf(&ret,"%s",p->u.ident);
} break;
case int_typ: {
asprintf(&ret,"%d",p->u.integ);
} break;
case string_typ: {
asprintf(&ret,"\"%s\"",p->u.str);
} break;
default: abort();
}
return ret;
} */
char * pp_val_entry(const val_entry * p) {
char * ret = 0;
switch(p->typ) {
case ident_typ: {
asprintf(&ret,"%s",p->u.ident);
} break;
case int64_typ: {
asprintf(&ret,"%lld",(long long int)p->u.integ);
} break;
case string_typ: {
asprintf(&ret,"\"%s\"",p->u.str);
} break;
default: abort();
}
return ret;
}
char * pp_col_entry(const col_entry * p) {
char * ret = 0;
switch(p->typ) {
case colint_typ: {
asprintf(&ret,"$%d",p->u.colnum);
} break;
case colstr_typ: {
asprintf(&ret,"$%s",p->u.colstr);
} break;
case string_typ: {
asprintf(&ret,"%s",p->u.colstr);
} break;
default: abort();
}
return ret;
}
char * pp_cmp_entry(const cmp_entry * p) {
char * ret = 0;
switch(p->lhs_typ) {
case col_typ: {
ret = afstrncat(ret, pp_col_entry(p->lhs.colent));
} break;
case val_typ: {
ret = afstrncat(ret, pp_val_entry(p->lhs.valent));
} break;
default: abort();
}
switch(p->comparator) {
case equal_typ: {
ret = astrncat(ret, "=");
} break;
default: abort();
}
switch(p->rhs_typ) {
case col_typ: {
ret = afstrncat(ret, pp_col_entry(p->rhs.colent));
} break;
case string_typ: {
ret = afstrncat(ret, pp_col_entry(p->rhs.colent));
} break;
case val_typ: {
ret = afstrncat(ret, pp_val_entry(p->rhs.valent));
} break;
default: abort();
}
return ret;
}
char * pp_typ_entry(const typ_entry * p) {
char * ret = 0;
switch(p->typ) {
case typ_typ: {
switch(p->u.type) {
case int64_typ: {
ret = astrncat(ret, "int");
} break;
case string_typ: {
ret = astrncat(ret, "string");
} break;
default: abort();
}
} break;
default: abort();
}
return ret;
}

View file

@ -0,0 +1,246 @@
#ifndef _REFER_AST_H
#define _REFER_AST_H
#include <stdint.h>
typedef struct expr_list expr_list;
typedef struct expr expr;
typedef struct query query;
typedef struct insert insert;
typedef struct delete delete;
typedef struct create create;
typedef struct q_scan q_scan;
typedef struct q_select q_select;
typedef struct q_project q_project;
typedef struct q_join q_join;
//typedef struct pat_tuple pat_tuple;
typedef struct cmp_tuple cmp_tuple;
typedef struct col_tuple col_tuple;
typedef struct val_tuple val_tuple;
typedef struct typ_tuple typ_tuple;
typedef struct union_typ union_typ;
typedef struct union_cmp union_cmp;
typedef struct union_qry union_qry;
//typedef struct pat_entry pat_entry;
typedef struct cmp_entry cmp_entry;
typedef struct col_entry col_entry;
typedef struct val_entry val_entry;
typedef struct typ_entry typ_entry;
typedef char* table;
typedef char* ident;
typedef int val_ent_wildcard;
typedef char* val_ent_ident;
typedef int64_t val_ent_int;
typedef char* val_ent_string;
#include "../tuple.h" // for datatypes.
/*typedef enum {
integer_data_typ,
string_data_typ
} val_ent_typ;*/
typedef int val_col_int;
typedef char* val_col_string;
struct expr_list {
int count;
expr ** ents;
};
char * pp_expr_list(const expr_list*);
struct expr {
enum expr_typ {
query_typ,
insert_typ,
delete_typ,
create_typ
} typ;
union {
union_qry * q;
insert * i;
delete * d;
create * c;
} u;
};
char * pp_expr(const expr*);
struct query {
enum query_typ {
scan_typ,
table_star_typ,
select_typ,
project_typ,
join_typ
} typ;
union {
q_scan * scn;
q_select * sel;
q_project* prj;
q_join * jn;
} u;
};
char * pp_query(const query*);
struct create {
char * tbl;
union_typ * schema;
};
char * pp_create(const create*);
struct q_scan {
char * table;
};
char * pp_q_scan(const q_scan*);
struct q_select {
union_cmp * t;
union_qry * q;
};
//char * pp_q_select(const q_select*);
struct q_project {
col_tuple * t;
union_qry * q;
};
//char * pp_q_project(const q_project*);
struct q_join {
cmp_tuple * t;
union_qry * lhs;
union_qry * rhs;
};
//char * pp_q_join(const q_join*);
struct insert {
table tbl;
val_tuple * t;
};
char * pp_insert(const insert*);
struct delete {
table tbl;
val_tuple * t;
};
char * pp_delete(const delete*);
enum cmp_typ {
equal_typ
};
/*struct pat_tuple {
int count;
pat_entry ** ents; // XXX tuple type?
};
char * pp_pat_tuple(const pat_tuple*); */
struct val_tuple {
int count;
val_entry ** ents;
};
char * pp_val_tuple(const val_tuple*);
struct col_tuple {
int count;
col_entry ** ents;
};
char * pp_col_tuple(const col_tuple*);
struct cmp_tuple {
int count;
cmp_entry ** ents;
};
char * pp_cmp_tuple(const cmp_tuple*);
struct typ_tuple {
int count;
typ_entry ** ents;
};
char * pp_typ_tuple(const typ_tuple*);
/*struct pat_entry {
enum tup_entry_typ typ;
union {
val_ent_wildcard wc;
val_ent_ident ident;
val_ent_int integ;
val_ent_string str;
} u;
};
char * pp_pat_entry(const pat_entry*); */
struct val_entry {
datatype_t typ;
union {
val_ent_ident ident;
val_ent_int integ;
val_ent_string str;
} u;
};
char * pp_val_entry(const val_entry*);
struct col_entry {
datatype_t typ;
union {
val_col_string colstr;
val_col_int colnum;
} u;
};
char * pp_col_entry(const col_entry*);
struct typ_entry {
datatype_t typ;
union {
datatype_t type;
} u;
};
char * pp_typ_entry(const typ_entry*);
struct union_typ {
int count;
typ_tuple ** ents;
};
char * pp_union_typ(const union_typ*);
struct union_cmp {
int count;
cmp_tuple ** ents;
};
char * pp_union_cmp(const union_cmp*);
struct union_qry {
int count;
query ** ents;
};
char * pp_union_qry(const union_qry*);
enum cmp_side_typ {
col_typ,
val_typ
};
struct cmp_entry {
enum cmp_side_typ lhs_typ;
enum cmp_side_typ rhs_typ;
enum cmp_typ comparator;
union {
col_entry * colent;
val_entry * valent;
} lhs;
union {
col_entry * colent;
val_entry * valent;
} rhs;
};
char * pp_cmp_entry(const cmp_entry*);
//int yyparse();
extern expr_list * results;
void parse(char *buf, expr_list **result);
char * astrncat(char *,const char *);
char * afstrncat(char *,char *);
/*struct table {
char * name;
};
char * pp_table(table*); */
/*struct ident {
char * name;
};
char * pp_ident(ident*); */
#endif// _REFER_AST_H

View file

@ -0,0 +1,79 @@
%{
#include <assert.h>
#include <string.h>
#include "ast.h"
#include "y.tab.h"
#include "parser_private.h"
//#define DBG(x) printf("%s\t",x); ECHO
#define DBG(x)
#define PARM yyget_extra(yyscanner)
#define YY_INPUT(buffer, res, max_size) \
do { \
if (PARM->pos >= PARM->length) \
res = YY_NULL; \
else \
{ \
res = PARM->length - PARM->pos; \
res > (int)max_size ? res = max_size : 0; \
memcpy(buffer, PARM->buf + PARM->pos, res); \
PARM->pos += res; \
} \
} while (0)
//%option reentrant bison-bridge
//%option noyywrap
//%option nounput
%}
%option reentrant bison-bridge
%option noyywrap
%option nounput
%START INTUPLE
%%
"(" {DBG("LPAREN"); BEGIN INTUPLE; return LPAREN;}
")" {DBG("RPAREN"); BEGIN 0; return RPAREN;}
"{" {DBG("LBRACKET"); return LBRACKET;}
"}" {DBG("RBRACKET"); return RBRACKET;}
"," {DBG("COMMA"); return COMMA;}
"|" {DBG("BAR"); return BAR;}
"*" {DBG("STAR"); return STAR;}
"=" {DBG("EQUAL"); return EQUAL;}
"insert" {DBG("INSERT"); return INSERT;}
"i" {DBG("INSERT"); return INSERT;}
"delete" {DBG("DELETE"); return DELETE;}
"d" {DBG("DELETE"); return DELETE;}
"query" {DBG("QUERY"); return QUERY;}
"q" {DBG("QUERY"); return QUERY;}
"create" {DBG("CREATE"); return CREATE;}
"c" {DBG("CREATE"); return CREATE;}
"string" {DBG("STRING_TYPE"); return STRING_TYPE;}
"int" {DBG("INT_TYPE"); return INT_TYPE;}
"s" {DBG("SELECT"); return SELECT;}
"select" {DBG("SELECT"); return SELECT;}
"p" {DBG("PROJECT"); return PROJECT;}
"project" {DBG("PROJECT"); return PROJECT;}
"j" {DBG("JOIN"); return JOIN;}
"join" {DBG("JOIN"); return JOIN;}
<INTUPLE>[A-Za-z_][A-Za-z0-9_]* {DBG("IDENT"); yylval->string = strdup(yytext);return IDENT; }
[A-Za-z_][A-Za-z0-9_]* {DBG("TABLE"); yylval->string = strdup(yytext); return TABLE; }
[-+]?[0-9]+ {DBG("INT"); yylval->number = atoi(yytext); /*XXX error checking*/return INT; }
$[A-Za-z_][A-Za-z0-9_]* {DBG("COLNAME"); yylval->string = strdup(yytext+1); return COLNAME; }
$[1-9][0-9]* {DBG("COLNUM"); yylval->number = atoi(yytext+1); /*XXX*/return COLNUM; }
$0 {DBG("COLNUM"); yylval->number = 0; return COLNUM; }
\"[^"]* {DBG("STRING");
if (yytext[yyleng-1] == '\\') {
yymore();
} else {
input(yyscanner);
yylval->string = strdup(yytext+1);
return STRING;
}
}
[ \t\n] DBG("WS");
%%

View file

@ -0,0 +1,25 @@
#include "ast.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char * argv[]) {
char * in = 0;
size_t len = 0;
char * buf = 0;
int read;
while(-1!=(read = getline(&in, &len, stdin))) {
// printf("->%s<-",in);
// fflush(NULL);
buf = astrncat(buf,in);
}
// int ret = yyparse();
expr_list * results = 0;
parse(buf, &results);
if(results) {
char * str = pp_expr_list(results);
printf("%s", str);
free(str);
}
return results == 0;
}

View file

@ -0,0 +1,295 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ast.h"
#include "/home/sears/stasis/src/apps/referential/lang/parser_private.h"
void parse(char *buf, expr_list **result)
{
parse_parm pp;
pp.buf = buf;
pp.length = strlen(buf);
pp.pos = 0;
*result = 0;
yylex_init(&pp.yyscanner);
yyset_extra(&pp, pp.yyscanner);
yyparse(&pp, pp.yyscanner);
*result = pp.result;
yylex_destroy(pp.yyscanner);
}
%}
%pure_parser
%parse-param {parse_parm *parm}
%parse-param {void *scanner}
%lex-param {yyscan_t *scanner}
//%}
%token LPAREN RPAREN LBRACKET RBRACKET
%token COMMA BAR STAR EQUAL
%token SELECT PROJECT JOIN
%token QUERY INSERT DELETE CREATE
/* The reserved words "string" and "int" */
%token STRING_TYPE
%token INT_TYPE
%union {
val_entry * val_ent;
col_entry * col_ent;
cmp_entry * cmp_ent;
typ_entry * typ_ent;
val_tuple * val_tup;
col_tuple * col_tup;
cmp_tuple * cmp_tup;
typ_tuple * typ_tup;
union_typ * union_typ;
union_cmp * union_cmp;
union_qry * union_qry;
insert * ins_expr;
delete * del_expr;
query * qry_expr;
create * crt_expr;
expr * expr;
expr_list * exprs;
char * string;
int number;
enum cmp_typ comparator;
}
%token <string> TABLE
%token <string> IDENT
%token <string> COLNAME
%token <number> COLNUM
%token <string> STRING
%token <number> INT
%type <val_ent> val
%type <col_ent> col
%type <cmp_ent> cmp
%type <typ_ent> typ
%type <comparator> test
%type <val_tup> val_list val_tuple
%type <col_tup> col_list col_tuple
%type <cmp_tup> cmp_list cmp_tuple
%type <typ_tup> typ_list typ_tuple
%type <union_typ> union_typ
%type <union_cmp> union_cmp
%type <union_qry> union_qry
%type <ins_expr> insert
%type <del_expr> delete
%type <qry_expr> query
%type <crt_expr> create
%type <expr> expr
%type <exprs> expr_list
%%
expr_list : expr { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; parm->result = $$; }
| expr_list expr
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $2;
}
expr : QUERY union_qry {
$$ = malloc(sizeof(*$$));
$$->typ = query_typ;
$$->u.q = $2;
}
| INSERT insert {
$$ = malloc(sizeof(*$$));
$$->typ = insert_typ;
$$->u.i = $2;
}
| DELETE delete {
$$ = malloc(sizeof(*$$));
$$->typ = delete_typ;
$$->u.d = $2;
}
| CREATE create {
$$ = malloc(sizeof(*$$));
$$->typ = create_typ;
$$->u.c = $2;
}
union_qry : query { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; }
| union_qry BAR query
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $3;
}
query : TABLE
{
$$ = malloc(sizeof(*$$)); $$->typ=scan_typ;
$$->u.scn = malloc(sizeof(*$$->u.scn));
$$->u.scn->table = $1;
}
| STAR
{
$$ = malloc(sizeof(*$$)); $$->typ=table_star_typ;
$$->u.scn = 0;
}
| LBRACKET SELECT union_cmp union_qry RBRACKET
{
$$ = malloc(sizeof(*$$)); $$->typ=select_typ;
$$->u.sel = malloc(sizeof(*$$->u.sel));
$$->u.sel->t = $3;
$$->u.sel->q = $4;
}
| LBRACKET PROJECT col_tuple union_qry RBRACKET
{
$$ = malloc(sizeof(*$$)); $$->typ=project_typ;
$$->u.prj = malloc(sizeof(*$$->u.prj));
$$->u.prj->t = $3;
$$->u.prj->q = $4;
}
| LBRACKET JOIN cmp_tuple union_qry union_qry RBRACKET
{
$$ = malloc(sizeof(*$$)); $$->typ=join_typ;
$$->u.jn = malloc(sizeof(*$$->u.jn));
$$->u.jn->t = $3;
$$->u.jn->lhs = $4;
$$->u.jn->rhs = $5;
};
insert : TABLE val_tuple { $$ = malloc(sizeof(*$$)); $$->tbl = $1; $$->t = $2; }
delete : TABLE val_tuple { $$ = malloc(sizeof(*$$)); $$->tbl = $1; $$->t = $2; }
create : TABLE union_typ { $$ = malloc(sizeof(*$$)); $$->tbl = $1; $$->schema = $2; }
val_tuple : LPAREN val_list RPAREN { $$ = $2; }
val_list : val { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; }
| val_list COMMA val
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $3;
}
val : IDENT { $$ = malloc(sizeof(*$$)); $$->typ = ident_typ; $$->u.ident = $1; }
| INT { $$ = malloc(sizeof(*$$)); $$->typ = int64_typ; $$->u.integ = $1; }
| STRING { $$ = malloc(sizeof(*$$)); $$->typ = string_typ; $$->u.str = $1; }
col_tuple : LPAREN col_list RPAREN { $$ = $2; }
| LPAREN RPAREN { $$ = malloc(sizeof(*$$)); $$->count = 0; $$->ents = malloc(1); }
col_list : col { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; }
| col_list COMMA col
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $3;
}
col : COLNUM { $$ = malloc(sizeof(*$$)); $$->typ = colint_typ; $$->u.colnum = $1; }
| COLNAME { $$ = malloc(sizeof(*$$)); $$->typ = colstr_typ; $$->u.colstr = $1; }
cmp_tuple : LPAREN cmp_list RPAREN { $$ = $2; }
| LPAREN RPAREN { $$ = malloc(sizeof(*$$)); $$->count = 0; $$->ents = malloc(sizeof(char)); }
cmp_list : cmp { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; }
| cmp_list COMMA cmp
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $3;
}
cmp : col test val { $$ = malloc(sizeof(*$$)); $$->lhs_typ = col_typ; $$->lhs.colent = $1;
$$->comparator = $2;
$$->rhs_typ = val_typ; $$->rhs.valent = $3; }
| val test col { $$ = malloc(sizeof(*$$)); $$->lhs_typ = val_typ; $$->lhs.valent = $1;
$$->comparator = $2;
$$->rhs_typ = col_typ; $$->rhs.colent = $3; }
| col test col { $$ = malloc(sizeof(*$$)); $$->lhs_typ = col_typ; $$->lhs.colent = $1;
$$->comparator = $2;
$$->rhs_typ = col_typ; $$->rhs.colent = $3; }
| val test val { $$ = malloc(sizeof(*$$)); $$->lhs_typ = val_typ; $$->lhs.valent = $1;
$$->comparator = $2;
$$->rhs_typ = val_typ; $$->rhs.valent = $3; }
| col { $$ = malloc(sizeof(*$$)); $$->lhs_typ = col_typ; $$->lhs.colent = $1;
$$->comparator = equal_typ;
$$->rhs_typ = col_typ; $$->rhs.colent = $1; }
| IDENT
{ $$ = malloc(sizeof(*$$)); $$->lhs_typ = col_typ; $$->lhs.colent = malloc(sizeof(*$$->lhs.colent));
$$->lhs.colent->typ=string_typ; $$->lhs.colent->u.colstr=$1;
$$->comparator = equal_typ;
$$->rhs_typ = col_typ; $$->rhs.colent = malloc(sizeof(*$$->rhs.colent));
$$->rhs.colent->typ=string_typ; $$->rhs.colent->u.colstr=$1; }
typ_tuple : LPAREN typ_list RPAREN { $$ = $2; }
typ_list : typ { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; }
| typ_list COMMA typ
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $3;
}
typ : STRING_TYPE
{
$$ = malloc(sizeof(*$$));
$$->typ = typ_typ;
$$->u.type = string_typ;
}
| INT_TYPE
{
$$ = malloc(sizeof(*$$));
$$->typ = typ_typ;
$$->u.type = int64_typ;
}
union_typ : typ_tuple { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; }
| union_typ BAR typ_tuple
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $3;
}
union_cmp : cmp_tuple { $$ = malloc(sizeof(*$$)); $$->count = 1; $$->ents = malloc(sizeof(*($$->ents))); $$->ents[0] = $1; }
| union_cmp BAR cmp_tuple
{
$$ = $1 ;
($$->count)++;
$$->ents = realloc($$->ents, sizeof(*($$->ents)) * ($$->count));
$$->ents[($$->count)-1] = $3;
}
test : EQUAL { $$ = equal_typ; }
%%
int yyerror(parse_parm * param, void * yyscanner, char * errMsg) {
printf("Error: %s\n", errMsg);
// XXX memory leak?
param->result = 0;
return 0;
}
int yywrap () { return 1; }
//#include "lex.yy.c"

View file

@ -0,0 +1,29 @@
/*
From:
http://www.usualcoding.eu/index.php?tag/flex
*/
typedef struct parse_parm_s
{
void *yyscanner;
char *buf;
int pos;
int length;
void *result;
} parse_parm;
//void parse(char *buf, expr_list **result);
//#define YYSTYPE
#define YY_EXTRA_TYPE parse_parm *
//int yylex(void /*YYSTYPE*/ *, void *);
int yylex_init(void **);
int yylex_destroy(void *);
void yyset_extra(YY_EXTRA_TYPE, void *);
int yyparse(parse_parm *, void *);
//void yyerror();

View file

@ -0,0 +1,92 @@
#!/usr/bin/perl -w
use strict;
my @winners;
my @losers;
#
# query tests
#
my $fail = 0;
push @winners, 'query foo';
push @winners, 'query foo1';
push @winners, 'query {s ($1=2,$2="asd",$3=x) foo}';
push @winners, 'query {p ($1,$2) foo}';
push @winners, 'query {j ($1=$4,"foo"=$3,$5=x,3=$6) foo bar}';
push @winners, 'query {select ($1=2,$2="asd",$3=x) foo}';
push @winners, 'query {project ($1,$2) foo}';
push @winners, 'query {join ($1=$4,"foo"=$3,$5=x,3=$6) foo bar}';
push @winners, 'query {
j
($1=$4,"foo"=$3,$5=x,3=$6)
{
s ($0="a",$2=1) foo
}
bar
}';
push @winners, 'query {select ($3 = "blue")|($3 = 10) questions_three}';
push @winners, 'query {project ($3){select($1="Galahad")questions_three}}';
push @winners, 'query {join ($MigratorID=$MigratorID) Migrators *}';
push @winners, 'query {join ($MigratorID) Migrators { join ($BirdId) Birds *} | Fruits }';
push @winners, 'query {join ($Type) * *}';
push @winners, 'query {project ($titl) {select ($author="sears") {join (docid) * *}}}';
push @losers, 'query 1';
push @losers, 'query foo 1';
push @losers, 'query {p (a,2) foo}';
push @losers, 'query {p (1,2) foo}';
push @losers, 'query {p ("a",$2) foo}';
push @losers, 'query {p ($1,"a") foo}';
push @losers, 'query {
j
($1=$4,"foo"=$3,$5=x,3=$6)
{
s ("a",*,1) foo
bar
}';
#
# insert tests
#
push @winners, 'insert foo (a,"1",1)';
push @winners, 'insert foo (a,"`1234567890-=~!@#$%^&*()+qwertyuiop[]\QWERTYUIOP{}|asdfghjkl;\\\'ASDFGHJKL:'."\n".'zxcvbnm,./ZXCVBNM<>?",1)';
push @winners, 'delete foo (a,"1",1)';
push @winners, 'delete foo (a,"`1234567890-=~!@#$%^&*()+qwertyuiop[]\QWERTYUIOP{}|asdfghjkl;\\\'ASDFGHJKL:'."\n".'zxcvbnm,./ZXCVBNM<>?",1)';
push @losers, 'delete foo (string,"1",1)';
push @losers, 'delete foo (int,"`1234567890-=~!@#$%^&*()+qwertyuiop[]\QWERTYUIOP{}|asdfghjkl;\\\'ASDFGHJKL:'."\n".'zxcvbnm,./ZXCVBNM<>?",1)';
push @winners, 'create foo (int, string, int)';
push @losers, 'create foo';
push @losers, 'create foo (int, string, "char")';
push @winners, 'create foo (int, string)|(string, int)';
foreach my $q (@winners) {
open TST, "| ./parser";
print TST $q;
if(!close TST) {
# command failed:
print "unexpected fail: $q\n";
$fail ++;
}
}
foreach my $q (@losers) {
open TST, "| ./parser";
print TST $q;
if(close TST) {
# command succeeded:
print "unexpected pass: $q\n";
$fail ++;
}
}
if($fail) {
exit(1);
}

View file

@ -1,26 +1,48 @@
query
query TABLES
query {s (1) TABLES}
query {s ($1) TABLES}
query {s ($1=TABLES) TABLES}
query {s ($0=TABLES) TABLES}
query {s ($0="TABLES") TABLES}
query {s ($1="TABLES") TABLES}
query {s (TABLES,*,*,*) TABLES}
query {s (TABLES,*,*,*,*) TABLES}
query {p (1,2,3,4) TABLES}
query {p ($1,$2,$3,$4) TABLES}
query {p (0,1,2,3) TABLES}
query {p ($0,$1,$2,$3) TABLES}
query {p ($0,$1,$2,$100) TABLES}
query {p (0,0,0,0) TABLES}
query {p (0,1,2,3,0,1,2,3,0) TABLES}
query {p ($0,$0,$0,$0) TABLES}
query {p ($0,$1,$2,$3,$0,$1,$2,$3,$0) TABLES}
query {p (0,1,2,3,0,1,2,3,0) xxx}
query {p ($0,$1,$2,$3,$0,$1,$2,$3,$0) xxx}
query {p (0) xxx}
query {p ($0) xxx}
query {s (*) xxx}
query {s () xxx}
query {s () TABLES}
query {j (1=1) xxx yyy}
query {j ($1=$1) xxx yyy}
query {p (a,b,c) TABLES}
query {p (0,1,2) TABLES}
query {p ($0,$1,$2) TABLES}
query {s () TABLES}
query {p () TABLES}
query {s () {p () TABLES} }
query {j () TABLES TABLES}
query {j ($0=$0) TABLES TABLES}
query {j (0=0) TABLES TABLES}
query {j (0=1) TABLES TABLES}
query {j (0=0,1=1) TABLES TABLES}
query {j ($0=$0,$1=$1) TABLES TABLES}
query {j (0=0,1=2) TABLES TABLES}
query {j ($0=$0,$1=$2) TABLES TABLES}
query {j ($0=$0,$1=$100) TABLES TABLES}
query {j (0<0) TABLES TABLES}
query {j ($0<$0) TABLES TABLES}
query {x y z}
create foo
insert foo bar

View file

@ -12,8 +12,14 @@
#include <stasis/transactional.h>
#include "algebra.h"
#include "tuple.h"
#include "ddl.h"
#include "dml.h"
#include "lang/ast.h"
//XXX#include "lang/context.h"
#define MAX_CONN_QUEUE 10
#define THREAD_POOL 20
#define SHUTDOWN_SERVER 1
@ -36,6 +42,8 @@ char interpreterStates[THREAD_POOL];
pthread_t interpreters[THREAD_POOL];
FILE * interpreterConnections[THREAD_POOL];
ReferentialAlgebra_context_t * context;
int openInterpreter(FILE * in, FILE * out, recordid hash);
void * interpreterThread(void * arg) {
@ -112,7 +120,7 @@ int openInterpreter(FILE * in, FILE * out, recordid hash) {
AUTOCOMMIT = 1;
Tcommit(xid);
}
} else if(!strncmp(line+1,"parseTuple",strlen("parseToken"))) {
/* } else if(!strncmp(line+1,"parseTuple",strlen("parseToken"))) {
char * c = line + 1 + strlen("parseToken");
char ** toks = parseTuple(&c);
for(int i = 0; toks[i]; i++) {
@ -123,7 +131,7 @@ int openInterpreter(FILE * in, FILE * out, recordid hash) {
strlen("parseExpression"))) {
char * c = line + 1 + strlen("parseExpression");
lladdIterator_t * it = parseExpression(xid, hash, &c);
it = 0;
it = 0; */
} else if(!strncmp(line+1,"exit",strlen("exit"))) {
break;
} else if(!strncmp(line+1,"shutdown",strlen("shutdown"))) {
@ -131,63 +139,51 @@ int openInterpreter(FILE * in, FILE * out, recordid hash) {
break;
}
} else {
if(!strncmp(line,"create",strlen("create"))) {
char * linecopy = strdup(line+strlen("create"));
char * strtoks;
char * tablename = strtok_r(linecopy, " \r\n",&strtoks);
size_t sz;
byte* delme;
if(AUTOCOMMIT) xid = Tbegin();
if(-1 == (sz=ThashLookup(xid, hash, (byte*)tablename,strlen(tablename)+1,&delme))) {
fprintf(out, "Creating table %s\n", tablename);
recordid newHash = ThashCreate(xid, VARIABLE_LENGTH, VARIABLE_LENGTH);
char * tpl = tplRid(newHash);
char * insert;
asprintf(&insert, "insert TABLES %s,%s\n", tablename, tpl);
executeInsert(xid, hash, insert);
free(insert);
free(tpl);
} else {
fprintf(out, "Table already exists: %s\n", tablename);
free(delme);
// assert(sz == sizeof(recordid));
}
if(AUTOCOMMIT) Tcommit(xid);
free(linecopy);
} else if(!strncmp(line,"query",strlen("query"))) {
char * linecopy = strdup(line+strlen("query"));
char ** result = executeQuery(xid, hash, linecopy);
int i = 0;
if(result) {
while(result[i]) {
fprintf(out, "%s\n", result[i]);
free(result[i]);
i++;
expr_list * results = 0;
parse(line, &results);
for(int i = 0; results && i < results->count; i++) {
expr * e = results->ents[i];
switch(e->typ) {
case query_typ: {
lladdIterator_t * it = ReferentialAlgebra_ExecuteQuery(xid, context, e->u.q);
if(it) {
while(Titerator_next(xid,it)) {
byte * tup;
Titerator_value(xid,it, &tup);
char * tupleString = stringTuple(*(tuple_t*)tup);
fprintf(out, "%s\n", tupleString);
free(tupleString);
}
Titerator_close(xid,it);
}
free(result);
} else {
fprintf(out, "query failed\n");
} break;
case insert_typ: {
if(AUTOCOMMIT) { xid = Tbegin(); }
ReferentialDML_ExecuteInsert(xid, context, e->u.i);
if(AUTOCOMMIT) { Tcommit(xid); xid = -1;}
} break;
case delete_typ: {
if(AUTOCOMMIT) { xid = Tbegin(); }
ReferentialDML_ExecuteDelete(xid, context, e->u.d);
if(AUTOCOMMIT) { Tcommit(xid); xid = -1;}
} break;
case create_typ: {
if(AUTOCOMMIT) { xid = Tbegin(); }
ReferentialDDL_CreateTable(xid, context, e->u.c);
if(AUTOCOMMIT) { xid = Tcommit(xid); xid = -1;}
} break;
default:
abort();
}
free(linecopy);
} else if(!strncmp(line,"insert",strlen("insert"))) {
if(AUTOCOMMIT) xid = Tbegin();
executeInsert(xid, hash, line);
if(AUTOCOMMIT) Tcommit(xid);
} else if(!strncmp(line,"delete",strlen("delete"))) {
if(AUTOCOMMIT) xid = Tbegin();
executeDelete(xid, hash, line);
if(AUTOCOMMIT) Tcommit(xid);
}
//XXX typecheck(context, results);
if(results) {
char * str = pp_expr_list(results);
printf("%s", str);
free(str);
} else {
fprintf(out, "I don't understand...\n");
printf("No results\n");
}
}
fprintf(out, "> ");
@ -318,14 +314,10 @@ int main(int argc, char * argv[]) {
assert(rootEntry.page == ROOT_RECORD.page);
assert(rootEntry.slot == ROOT_RECORD.slot);
hash = ThashCreate(xid, VARIABLE_LENGTH, VARIABLE_LENGTH);
hash = ReferentialAlgebra_allocContext(xid);
Tset(xid, rootEntry, &hash);
char * tpl = tplRid(hash);
ThashInsert(xid,hash,(byte*)"TABLES", strlen("TABLES")+1, (byte*)tpl, strlen(tpl)+1);
} else {
printf("Opened existing store\n");
rootEntry.page = ROOT_RECORD.page;
@ -333,8 +325,11 @@ int main(int argc, char * argv[]) {
rootEntry.size = sizeof(recordid);
Tread(xid, rootEntry, &hash);
}
context = ReferentialAlgebra_openContext(xid,hash);
Tcommit(xid);
FILE * in;

View file

@ -0,0 +1,249 @@
#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
//#include "old_algebra.h"
#include "tuple.h"
#include "lang/ast.h"
/*char * tplRid(recordid rid) {
char * ret;
asprintf(&ret, "%d,%d,%lld", rid.page, rid.slot, (long long)rid.size);
return ret;
}
recordid ridTpl(char * tpl) {
int count;
char * freeme;
char ** tok = split(tpl, &freeme, &count, ", ");
recordid ret;
errno = 0;
assert(count == 3);
ret.page = strtol(tok[0],NULL,10);
ret.slot = strtol(tok[1],NULL,10);
ret.size = strtol(tok[2],NULL,10);
if(errno) {
perror("Couldn't parse rid");
abort();
}
free(freeme);
free(tok);
return ret;
}
char ** tplDup(char ** tup) {
int i = 0;
for(; tup[i]; i++) { } // i = num non-null entries
char ** ret = malloc(sizeof(char**) * (i+1));
ret[i] = 0;
while(i) {
i--;
ret[i] = strdup(tup[i]);
}
return ret;
}
void tplFree(char ** tup) {
for(int i = 0; tup[i]; i++) {
free(tup[i]);
}
free(tup);
}*/
tuple_t tupleRid(recordid rid) {
tuple_t ret;
ret.count = 3;
ret.type = malloc(sizeof(datatype_t)*3);
ret.col = malloc(sizeof(tuplecol_t)*3);
ret.type[0] = int64_typ;
ret.type[1] = int64_typ;
ret.type[2] = int64_typ;
ret.col[0].int64 = rid.page;
ret.col[1].int64 = rid.slot;
ret.col[2].int64 = rid.size;
return ret;
}
recordid ridTuple(tuple_t tup) {
recordid ret = { tup.col[0].int64, tup.col[1].int64, tup.col[2].int64 };
return ret;
}
tuple_t tupleDup(tuple_t tup) {
tuple_t ret;
ret.count = tup.count;
ret.type = malloc(sizeof(*ret.type)*tup.count);
ret.col = malloc(sizeof(*ret.col)*tup.count);
memcpy(ret.type, tup.type, sizeof(*ret.type)*tup.count);
for(col_t i = 0; i < tup.count; i++) {
switch(ret.type[i]) {
case int64_typ: {
ret.col[i].int64 = tup.col[i].int64;
} break;
case string_typ: {
ret.col[i].string = strdup(tup.col[i].string);
} break;
default: abort();
}
}
return ret;
}
void tupleFree(tuple_t tup) {
for(col_t i = 0; i < tup.count; i++) {
switch(tup.type[i]) {
case int64_typ: {
// nop
} break;
case string_typ: {
free(tup.col[i].string);
} break;
default: abort();
}
}
if(tup.col) { free(tup.col); }
if(tup.type) { free(tup.type); }
}
tuple_t tupleAlloc() {
tuple_t ret;
ret.count = 0;
ret.type = 0;
ret.col = 0;
return ret;
}
tuple_t tupleCatInt64(tuple_t t, int64_t i) {
t.count++;
t.type = realloc(t.type,t.count * sizeof(t.type[0]));
t.col = realloc(t.col,t.count * sizeof(t.col[0]));
t.type[t.count-1] = int64_typ;
t.col[t.count-1].int64 = i;
return t;
}
tuple_t tupleCatString(tuple_t t, const char * str) {
t.count++;
t.type = realloc(t.type,t.count * sizeof(t.type[0]));
t.col = realloc(t.col,t.count * sizeof(t.col[0]));
t.type[t.count-1] = string_typ;
t.col[t.count-1].string = strdup(str);
return t;
}
tuple_t tupleCatCol(tuple_t t, tuple_t src, col_t i) {
if(src.type[i] == string_typ) {
t = tupleCatString(t, src.col[i].string);
} else if (src.type[i] == int64_typ) {
t = tupleCatInt64(t, src.col[i].int64);
}
return t;
}
tuple_t tupleCatTuple(tuple_t t, tuple_t src) {
for(int i = 0; i < src.count; i++) {
t = tupleCatCol(t, src, i);
}
return t;
}
tuple_t tupleTail(tuple_t src, col_t start_pos) {
tuple_t t = tupleAlloc();
for(int i = start_pos; i < src.count; i++) {
t = tupleCatCol(t, src, i);
}
return t;
}
byte * byteTuple(tuple_t t,size_t* s) {
byte * b;
*s = sizeof(col_t) + t.count * (sizeof(datatype_t));
for(col_t i = 0; i<t.count; i++) {
(*s)+= (t.type[i] == int64_typ ? sizeof(int64_t)
: (strlen(t.col[i].string)+1));
}
b = malloc(*s);
byte * next_b = b;
(*(col_t*)next_b) = t.count;
next_b += sizeof(col_t);
size_t typlen = sizeof(datatype_t)*t.count;
memcpy(next_b,t.type,typlen);
next_b += typlen;
for(col_t i = 0; i<t.count; i++) {
if(t.type[i] == int64_typ) {
*(int64_t*)next_b = t.col[i].int64;
next_b += sizeof(int64_t);
} else {
assert(t.type[i] == string_typ);
size_t len = strlen(t.col[i].string)+1;
memcpy(next_b, t.col[i].string, len);
next_b += len;
}
}
return b;
}
char * stringTuple(tuple_t t) {
char * ret = astrncat(0,"(");
for(int i = 0; i < t.count; i++) {
if(i) { ret = astrncat(ret, ","); }
if(t.type[i] == int64_typ) {
char * tok;
asprintf(&tok,"%lld",(long long)t.col[i].int64);
ret = afstrncat(ret,tok);
} else if(t.type[i] == string_typ) {
ret = astrncat(ret,t.col[i].string);
} else {
abort();
}
}
ret = astrncat(ret,")");
return ret;
}
tuple_t tupleByte(byte* b) {
tuple_t t;
t.count = *(col_t*)b;
// printf("deserialized size: %d\n", t.count);
byte * b_next = b;
b_next += sizeof(col_t);
size_t typelen = sizeof(datatype_t)*t.count;
t.type = malloc(typelen);
memcpy(t.type, b_next, typelen);
b_next+=typelen;
t.col = malloc(sizeof(tuplecol_t)*t.count);
for(col_t i = 0; i < t.count; i++) {
if(t.type[i] == int64_typ) {
t.col[i].int64 = *(int64_t*)b_next;
b_next += sizeof(int64_t);
} else {
size_t len = strlen((char*)b_next)+1;
t.col[i].string = malloc(len);
strcpy(t.col[i].string,(char*)b_next);
b_next += len;
}
}
return t;
}
tuple_t tupleVal_tuple(val_tuple * v) {
tuple_t t = tupleAlloc();
for(int i = 0; i < v->count; i++) {
if(v->ents[i]->typ == string_typ) {
t = tupleCatString(t, v->ents[i]->u.str);
} else if(v->ents[i]->typ == int64_typ) {
t = tupleCatInt64(t, v->ents[i]->u.integ);
} else if(v->ents[i]->typ == ident_typ) {
abort();
} else {
abort();
}
}
return t;
}
tuple_t tupleUnion_typ(union_typ * v) {
assert(v->count == 1);
tuple_t t = tupleAlloc();
typ_tuple * tt = v->ents[0];
for(int i = 0; i < tt->count; i++) {
assert(tt->ents[i]->typ == typ_typ);
t = tupleCatInt64(t, tt->ents[i]->u.type);
}
return t;
}

View file

@ -0,0 +1,51 @@
#include "lang/ast.h"
#ifndef TUPLE_H
#define TUPLE_H
#include <stasis/transactional.h>
#include <ctype.h>
typedef uint8_t col_t;
typedef enum {
star_typ,
ident_typ,
int64_typ,
string_typ,
colint_typ,
colstr_typ,
typ_typ,
} datatype_t;
typedef union {
int64_t int64;
char * string;
} tuplecol_t;
typedef struct tuple_t {
col_t count;
datatype_t * type;
tuplecol_t * col;
} tuple_t;
tuple_t tupleRid(recordid rid);
recordid ridTuple(tuple_t tpl);
char * stringTuple(tuple_t);
byte * byteTuple(tuple_t,size_t*);
tuple_t tupleByte(byte*);
tuple_t tupleVal_tuple(val_tuple * t);
tuple_t tupleUnion_typ(union_typ * t);
tuple_t tupleDup(tuple_t tup);
void tupleFree(tuple_t tup);
tuple_t tupleAlloc();
tuple_t tupleCatString(tuple_t t, const char * str);
tuple_t tupleCatInt64(tuple_t t, int64_t str);
tuple_t tupleCatCol(tuple_t t, tuple_t src, col_t col);
tuple_t tupleCatTuple(tuple_t t, tuple_t src);
tuple_t tupleTail(tuple_t t, col_t start_pos);
#endif //TUPLE_H/