B A S T A R D   S Q L

You knew it had to happen, didn't you? After all, we have a database, and
we're bastards. We bastardized Typhoon, we bastardized EiC, and now we're
going to bastardize SQL.


The Bastard Database or BDB is not a 'real' database: it is embedded and highly
specific, meaning standard database services like creating and deleting tables
are not supported.

Supported SQL Commands
----------------------
SELECT INSERT DELETE UPDATE

Unsupported SQL Commands
------------------------
CREATE DROP COMMIT ROLLBACK AUTHORIZATION 

The SQL parser in the famous 'Lex & Yacc' defines 3 statement types or sub-
languages within SQL: schema statements, module statements, and manipulative
statements. BSQL only supports manipulative statements.






BSQL Parse Tree
---------------

The parse tree generated by the SQL parser uses nodes of the format
	struct TREENODE {
		TREENODE_FN op;
		struct TREENODE *p *lc, *rc;
	};
where 'p' stands for 'parent', 'lc' stands for 'left child', and 'rc' stands
for 'right child'. The 'op' function represents the type of the node: each
node has an associated op() routine which performs a specific function and
returns an appropriate value. When bsql_exec() traverses the tree, it simply
calls op() for the root node; the root node then calls the op() for each of
its children, who then call op() for their children, and so on until a leaf
node is reached.

A leaf node has the format
	struct TREELEAF {
      	TREENODE_FN op;
      	struct TREENODE *p;
      	int type;
      	union {
            	char c;
            	unsigned char uc;
            	short s;
            	unsigned short us;
            	int i;
            	unsigned int ui;
            	long l;
            	unsigned long ul;
            	char *str;
            	struct BSQL_COL *col;         /* ref to a BSQL column */
            	struct db_table *table;       /* ref to a Typhoon Table */
      	}u;
	};
with 'p' once again standing for parent. The op() for a leaf node returns the
value which it contains in 'u'.



Top-Level Nodes
---------------
There are four top-level nodes, one for each supported command:

	INSERT
	UPDATE
	DELETE
	SELECT

The INSERT node contains the op() function
	int bsql_insert_nodeop( struct TREENODE *n, void *data );
which returns the number of items inserted. The INSERT node has two children:
	LEFT: Any node returning a BSQL_TMPTBL which contains the rows to be
            inserted [ the INSERT_ASGN node is used for this ]
	RIGHT: A leaf node containing the ID of the Typhoon table which the
		insert is to be performed on [stored in u.table]

The UPDATE node contains the op() function
	int bsql_update_nodeop( struct TREENODE *n, void *data );
which returns the number of items updated; it has two children:
	LEFT: Any node returning a BSQL_TMPTBL which contains the rows to be
            updated [ the UPD_ASGN node is used for this ]
	RIGHT: A leaf node containing the ID of the Typhoon table which the
		update is to be performed on [stored in u.table]

The DELETE node contains the op() function
	int bsql_delete_nodeop( struct TREENODE *n, void *data );
which returns the number of items deleted; it has two children:
	LEFT: Any node returning a BSQL_TMPTBL which contains the rows to be
            deleted [ the TABLE_SEL node is used for this ]
	RIGHT: A leaf node containing the ID of the Typhoon table which the
		delete is to be performed on [stored in u.table]

The SELECT node contains the op() function
	char * bsql_select_nodeop( struct TREENODE *n, void *data );
which returns a character string containing the delimited table that results
from the select [field and record delimiters are set in BSQL_SETTINGS]. The
SELECT node has one child:
	LEFT: Any node returning a BSQL_TMPTBL which contains the results of 
		the select. Typically the SUB_SEL or TABLE_SEL nodes are used
		for this.
The RIGHT child is NULL.


The Secondary Nodes
-------------------

INSERT_ASGN
	LEFT: SUB_SEL	[fields to update]
	RIGHT: ASGN		[values to fill them with]

UPDATE_ASGN
	LEFT: SUB_SEL 	[fields/rows to update]
	RIGHT: ASGN		[values to update them with]

SUB_SEL
	LEFT: TABLE_SEL 	[results of select]
	RIGHT: COL_LST	[fields to print]

TABLE_SEL
	LEFT: JOIN OR TABLE_SEL or TABLE_CPY or SUB_SELECT [table to select from]
	RIGHT: Boolean or Comparison Node

JOIN
	LEFT: TBL_LST
	RIGHT:	Boolean or Comparison node


The Tertiary Nodes
------------------
TABLE_CPY
	LEFT: NULL
	RIGHT: VAL_REF [table to copy]

COL_LST
	LEFT: COL_LST or NULL
	RIGHT: VAL_REF

VAL_LST
	LEFT: VAL_LST or NULL
	RIGHT: VAL_REF

TBL_LST	
	LEFT:		TBL_LST or NULL
	RIGHT:	TBL_CPY or TBL_SEL or JOIN or SUB_SELECT

ASGN
	LEFT: STATIC_ROW or TABLE_SEL or SUB_SEL or TBL_CPY [values to assign]
	RIGHT: COL_LIST [columns to assign to]

STATICROW
	LEFT: VAL_LIST [values to assign]
	RIGHT: NULL


The Boolean Nodes
-----------------
BOOL_AND
	LEFT: boolean or comparison
	RIGHT: boolean or comparison
BOOL_OR
	LEFT: boolean or comparison
	RIGHT: boolean or comparison
BOOL_NOT
	LEFT: NULL 
	RIGHT: boolean or comparison


The Comparison Nodes
--------------------
	LEFT: Mathop or VAL_REF
	RIGHT: Mathop or VAL_REF
COMP_LT
COMP_LE
COMP_EQ
COMP_GE
COMP_GT
COMP_NE


The Mathematical Nodes
----------------------
	LEFT: Mathop or VAL_REF
	RIGHT: Mathop or VAL_REF
MATHOP_ADD
MATHOP_SUB
MATHOP_MUL
MATHOP_DIV
MATHOP_AND
MATHOP_OR
MATHOP_XOR


The Leaf Node
-------------
VAL_REF




