%{
static	char ami_parser_y[] = 
"$Header: ami_parser.y,v 1.2 89/02/02 15:57:27 dillon Exp $";
/**********************************************************************
   
  ami_parser.y
  parser for amiint v2.15
  5/24 	:	open
		create
		close

 **********************************************************************/

#include "ami.h"
#define TRUE 1
#define FALSE 0

#define DO_QUERY(query) { StartTransactionCommand();\
			  startmmgr(0);\
			  query;\
			  CommitTransactionCommand();\
			  endmmgr(0);\
			  EMITPROMPT;\
			}

#define DO_START { StartTransactionCommand();\
		   startmmgr(0);\
		 }

#define DO_END   { CommitTransactionCommand();\
		   endmmgr(0);\
		   EMITPROMPT;\
		 }

int num_tuples_read = 0;
static OID oid;

%}

%token OPEN CLOSE CREATE P_RELN INSERT_TUPLE QUIT
%token ID STRING FLOAT INT DEFINE MACRO 
%token COMMA COLON DOT EQUALS LPAREN RPAREN AS IN TO
%token DESTROY RENAME RELATION ATTR ADD
%token DISPLAY OBJ_ID
%start Queries

%nonassoc low
%nonassoc high

%%

Queries:  Query Queries
	|
	;

Query :
  	  OpenStmt
	| CloseStmt 
	| PrintStmt
	| CreateStmt
	| DestroyStmt
	| InsertStmt 
	| QuitStmt
	| MacroDefStmt
	| RenameRelnStmt
	| RenameAttrStmt
  	| AddAttrStmt
	| DisplayStmt
	;

DisplayStmt:
	  DisplayMacro
	| DisplayReln
	;

DisplayMacro:
	  DISPLAY MACRO 
		{ 
		  DO_START;
		  printmacros(); 
		  DO_END;
		}
	;

DisplayReln:
	  DISPLAY RELATION
		{
		  DO_START;
		  openrel("pg_relation");
		  printrel();
		  closerel("pg_relation");
		  DO_END;
		}
	;

MacroDefStmt:
	  DEFINE MACRO ident EQUALS ident
		{ /* for now, simple subst only */
		  DO_START;
		  DefineMacro($3,$5);
		  DO_END;
		}
	;
AddAttrStmt:
	  ADD LPAREN {numattr=0;} typelist RPAREN TO ident
		{ DO_START;
		  AddAttr(LexIDStr($6));
		  DO_END;
		}
	;

PrintStmt: P_RELN
		{ DO_START; printrel(); DO_END;}
	;


OpenStmt: 
	  OPEN ident
		{ DO_START; openrel(LexIDStr($2)) ;DO_END; 
		}	
	| OPEN LPAREN typelist RPAREN AS ident
		{ DO_START;
		  createrel(LexIDStr($6));
		  DO_END;
		}
	;

CloseStmt:
	  CLOSE ident %prec low
		{ DO_START; closerel($2); DO_END; }
	| CLOSE %prec high
		{ DO_START; closerel(); DO_END; }
	;

DestroyStmt:
	  DESTROY ident
		{ DO_START; amdestroy(LexIDStr($2)); DO_END;}
	;

RenameRelnStmt:
	  RENAME RELATION ident AS ident
		{ DO_START; renamerel(LexIDStr($3),LexIDStr($5)); DO_END; }
	;

RenameAttrStmt:
	  RENAME ATTR ident AS ident IN ident
		{ DO_START;
		  renameatt(LexIDStr($7),LexIDStr($3),LexIDStr($5));
		  DO_END;
		}
	;
CreateStmt:
	  CREATE ident LPAREN 
		{ DO_START; 
		  numattr=(int)0;
		}
	  typelist 
		{ DO_END; }
	  RPAREN 
		{ DO_START; 
		  amcreate(LexIDStr($2),'n',numattr,attrtypes);
		  DO_END;}
	;
typelist:
	  typething
	| typething COMMA typelist
	;

typething:
	  ident EQUALS ident
		{ 
		   char name[16],type[16];
		   if(++numattr > MAXATTR)
			elog(FATAL,"Too many attributes\n");
		   DefineAttr(LexIDStr($1),LexIDStr($3),numattr-1);
		   printf("\n");
		}
	;

InsertStmt:
	  INSERT_TUPLE OBJ_ID EQUALS ident 
		{ printf("tuple %d<",atol(LexIDStr($4)));
		  num_tuples_read = 0;
		}
	  LPAREN  tuplelist RPAREN
  		{
		  HeapTuple tuple;
		  printf("nattr = %d, ntuples = %d\n",numattr,num_tuples_read);
		  if(num_tuples_read != numattr)
		    elog(WARN,"incorrect number of values for tuple");
		  if(reldesc==(Relation)NULL) {
		    elog(WARN,"must OPEN RELATION before INSERT\n");
		    err();
		  }
		  DO_START;
		  oid = atol(LexIDStr($4));
		  InsertOneTuple(oid);
		  DO_END;
		} 
	;

tuplelist:
	   tuple
	|  tuple COMMA tuplelist
	;

tuple:
	  ident
		{InsertOneValue(oid,LexIDStr($1),num_tuples_read++);}
	;
QuitStmt:
	  QUIT
		{
		  StartTransactionCommand();
		  startmmgr(0);
		  cleanup();
		}
	;
  
ident :
	 ID
		{$$=yylval;}
	| MACRO
		{$$=yylval;}
	;

%%


