/************************************************************************
*                       - INFOFLEX System -
* This source code is CONFIDENTIAL and PROPRIETARY to INFOFLEX ,
* INC. . The information contained herein may not be used, copied or
* disclosed in whole or in part except as permitted by written agreement
* signed by an officer of INFOFLEX,INC..
*
* COPYRIGHT (c) 1986 INFOFLEX , INC., BURLINGAME, CALIFORNIA.
* ALL RIGHTS RESERVED.
*************************************************************************/

/*
 * Include file: sqlfx.h
 * Description:  Main include file for Sqlflex.
 *		 Contains SQL structures, defines, macros,
 *		 and external references.
 */


#ifndef SQLFX_N
#define SQLFX_N

#include "sqflex.h"
#include "sqsyscat.h"
#include "sqlhdr.h"
#include "valfuncs.h"

/* Old SQL script runnner name.
 */

#define SELLIST    0

/* Expression factor types
 */
#define CONSTANT   1			/* constant */
#define VARIABLE   2			/* variable */
#define SGLFIELD   3			/* single field */
#define AGGREGATE  4			/* aggregate function */
#define DATEFUNC   5			/* date function */
#define NESTEXPR   6			/* nested expression */
#define HOSTVAR    7			/* host variable */

/* Optional SELECT clauses - main SELECT as well as subqueries
 */
#define WHERE	   1
#define HAVING	   2
#define GROUP	   3
#define ORDER	   4
#define INTO	   5
#define FORUPD	   6

/* Other SQL clauses
 */
#define UPDSET	   7

/* Boolean operators
 */
#undef	OP_LT
#define OP_EQ	    1
#define OP_NE	    2
#define OP_LT	    3
#define OP_GT	    4
#define OP_LE	    5
#define OP_GE	    6
#define OP_IN	    7
#define OP_BETWEEN  8
#define OP_MATCHES  9
#define OP_LIKE	   10
#define OP_ISNULL  11

/* Subquery array operators
 */
#define EXISTS	   1
#define ANY	   2
#define ALL	   3

/* Date functions
 */
#define DF_DAY	   1
#define DF_MONTH   2
#define	DF_YEAR	   3
#define DF_WEEKDAY 4
#define DF_MDY	   5
#define DF_DATE	   6

/* Aggregate functions:
*/
#undef  MAX
#undef  MIN
#define COUNT	   1
#define COUNTA	   2		/* count(*) */
#define COUNTU	   3		/* count(unique) */
#define MAX	   4
#define MIN	   5
#define SUM	   6
#define AVG	   7

/* GRANT privileges:
 */
#define PRV_SELECT	 1
#define PRV_UPDATE	 2
#define PRV_INSERT	 4
#define PRV_DELETE	 5
#define PRV_INDEX	 6
#define PRV_ALTER	 7
#define PRV_ALL		 8
#define PRV_CONNECT	10
#define PRV_RESOURCE	11
#define PRV_DBA		12

#define ALSNAMSIZ   TBLNAMSIZ
#define MAXORDFLDS  20

/* Definitions specific to NetISAM.
 */
#ifdef NETISAM
#define MINNETILEN  4			/* minimum length of a record */
#define NETIFILLFLD "__fIlLtOlEn4"	/* filler field to fill record out
					      to minimum length */
#endif

#define FXEOF	     -1
#define LINELEN	   2048
#define TAB	   '\t'

/* The SELECT tree structure
 */
struct _S_SFIELD {
	char	 slfFnam[FLDNAMSIZ+1];	/* field name */
	char *	 slfTbl;		/* table */
	char *	 slfOwner;		/* owner */
	DBFIELD *slfFptr;		/* pointer to table field structure */
	short	 slfStart;		/* substring start */
	short	 slfEnd;		/* substring end */
	short	 slfIsrowid;	 	/* is the field ROWID? */
};
typedef struct _S_SFIELD  SFIELD;

struct _dtexpr {
	VALUE	sdtVal;			/* value and type */
	SFIELD	sdtFld;			/* table field */
	char	sdtAddop;		/* operator: '+' or '-' */
	struct _dtexpr *sdtRexp;	/* right date expression operand */
};
typedef struct _dtexpr  DTEXPR;

struct _S_DTFUNC {
	short	sdfType;		/* DAY, MONTH, YEAR, WEEKDAY */
	DTEXPR	sdfDtexp;		/* argument to date functon */
};
typedef struct _S_DTFUNC  DTFUNC;

struct _S_FACTOR {
	VALUE	sfcVal;			/* value and type */
	short	sfcSign;		/* 1 = positive, -1 = negative */
	short	sfcEtype;		/* expression type: CONSTANT,	
					      VARIABLE, SGLFIELD, AGGREGATE,
					      DATEFUNC, NESTEXPR, HOSTVAR */
	DTFUNC *sfcDtfunc;		/* date function */
	short	sfcAggreg;		/* aggregate type: COUNT, COUNTA,
					      MAX, MIN, SUM, AVG */
	long    sfcNonullcount;		/* count of applicable records for
					      AVG aggregate (NULLs ignored) */
	SFIELD	sfcFld;			/* field description */
	struct _expr *	sfcExp;		/* nested expression */
	struct _hostv *	sfcHostvar;	/* pointer to host variable structure */
};
typedef struct _S_FACTOR FACTOR;

struct _term {
	FACTOR	stmFact;		/* left factor operand */
	char	stmMultop;		/* operator: '*' or '/' */
	struct _term *	stmRtrm;	/* right term operand */
};
typedef struct _term  TERM;

struct _expr {
	short	 sxpType;		/* data type, in sqtypes.h */
	short	 sxpSiz;		/* data size */
	short	 sxpOffs;		/* beginning byte within substring,
					      or number of bytes right of
					      decimal for decimal type,
					      or qualifier of DATETIME type. */
	short	 sxpIsagg;		/* aggregate function within exp. */
	TERM	 sxpTerm;		/* left term operand */
	char	 sxpAddop;		/* operator: '+' or '-' */
	struct _expr *	sxpRexp;	/* right expression operand */
	char	 sxpFldnm[FLDNAMSIZ+1];	/* field name if only one field in
					      expression, "2" if more than
					      one field */
	char	 sxpLabel[FLDNAMSIZ+1];	/* select list label */
	short	 sxpSort;		/* label in ORDER BY list? */
	short	 sxpAutlbl;		/* label auto-generated? */
	char *	 sxpAlltbl;		/* table.* in the select list */
	char *	 sxpAllowner;		/* owner of table.* */
	struct _expr *	 sxpNexp;	/* next expression of select list */
	short	 sxpLendisp;		/* field display widths */
	char *	 sxpP;			/* pointer to expression text */
};
typedef struct _expr  EXPR;

struct _bracket {
	VALUE	sbkBegval;		/* beginning value of bracketed range */
	short	sbkBincl;		/* range inclusive of beginning value */
	VALUE	sbkEndval;		/* ending value of bracketed range */
	short	sbkEincl;		/* range inclusive of ending value */
	struct _bracket *sbkNext;	/* next bracketed range */
};
typedef struct _bracket  VALBRACK;

struct _listv {
	VALUE	slvVal;			/* value and type */
	short	slvTo;			/* TO range operator */
	struct _hostv *	slvHostvar;	/* pointer to host variable structure */
	struct _listv *	slvNxt;		/* next value in list */
};
typedef struct _listv  LISTV;

struct _optiminfo {
	SFIELD *  sopFld;		/* pointer to field of WHERE clause */
	short	  sopCount;		/* number of times field in factor */
	short     sopIdxok;		/* field can be used in index */
	VALBRACK *sopBracket;		/* range of possible constant values */
	VALBRACK *sopDynabrk;		/* dynamic range of possible values */
	VALBRACK *sopBrkbuf;		/* pointer to initial allocation of
					      sopBracket or sopDynabrk */
	short	  sopHost;		/* single field compared to host
					      variable(s) */
	short	  sopUnionbrk;		/* any constant or host brackets
					      across all factors for field? */
	short	  sopUnionjoin;		/* any join criteria across all factors
					      for field? */
	short	  sopSubquery;		/* bracketed on results of subquery? */
	struct _optiminfo *sopNext;	/* optimization info for next field */
};
typedef struct _optiminfo  OPTIMINFO;

struct _bfactor {
	short	sbfFlag;		/* 0=false, 1=true, -2=undefined */
	short	sbfNot;			/* NOT operator */
	EXPR	sbfLexp;		/* left expression */
	short	sbfBop;			/* boolean comparator */
	EXPR *	sbfRexp;		/* right expression */
	short	sbfQop;			/* subquery operator:
					      EXISTS, ANY, ALL */
	short	sbfSubqfact;		/* subquery factor auto-generated for
					      relation with outer SELECT? */
	struct _select *sbfSlct;	/* nested select */
	LISTV *	sbfVlst;		/* value list */
	struct _cond *	sbfCond;	/* nested condition */
	OPTIMINFO    *	sbfOptim;	/* table access optimization info */
	struct _bfactor *sbfOrigfact;	/* pointer of factor copy to its
					      original (used when distributing
					      factors) */
	struct _bfactor *sbfCopyfact;	/* pointer of original factor to its
					      copy (also used when coping whole
					      SELECT statements) */
};
typedef struct _bfactor  BFACTOR;

struct _S_SELINDEX {
	BFACTOR * sdxBfact;		/* boolean factor with join fields */
	VALBRACK *sdxCurbrack;		/* current bracket of range */
};
typedef struct _S_SELINDEX  SELINDEX;

struct _selflds {
	SFIELD *ssfFld;			/* pointer to field structure */
	short	ssfClausin;		/* clauses field is in
					      001 - SELECT list
					      002 - WHERE
					      004 - HAVING
					      010 - GROUP */
	short	ssfTotemp;		/* WHERE clause field that must be
					      written to temp table */
	struct _selflds *ssfNfld;	/* pointer to next field of FROM tbl */
};
typedef struct _selflds  SELFLDS;

struct _frmtbl {
	char	 sftTnam[TBLNAMSIZ+1];	/* table name */
	char	 sftAlias[ALSNAMSIZ+1]; /* table alias */
	char	 sftOwner[USERNAMSIZ+1]; /* owner name */
	DBHEAD * sftTptr;		/* pointer to table header structure */
	struct _select *sftSelect;	/* pointer to the SELECT structure */
	long	 sftRecnum;		/* current record number */
	long	 sftSavnum;		/* saved record number */
	DBINDEX *sftIndex;		/* pointer to DBINDEX structure */
	short	 sftRevidx;		/* access in reverse index order? */
	short	 sftByrowid;		/* access by ROWID? */
	short	 sftBrkend;		/* end of unique index bracket? */
	short    sftOutergrp;		/* outer join group */
	short    sftOutparent;		/* parent outer join group */
	short	 sftOuterjoin;		/* is table OUTER joined? */
	struct _frmtbl *sftPrimeout;	/* primary table of OUTER join group */
	short    sftOutnull;		/* NULL result for OUTER join group? */
	SELINDEX sftIdxrel[NPARTS];	/* relations of index parts */
	struct _frmtbl *sftNtbl;	/* next table of FROM table list */
	SELFLDS *sftSflds;		/* list of fields in SELECT */
	long	 sftTbl4sprv;		/* table i.d. for field level SELECT
					      permission check (0 = no check) */
	long	 sftTbl4uprv;		/* table i.d. for field level UPDATE
					      permission check (0 = no check) */
	short	 sftFlag;		/* optimization flag:
					      inititally set to 1 if table used;
					      then set to access order number */
	DBHEAD * sftTmptp;		/* pointer of temporary table to provide
					      alternate index */
	char *	 sftDhbuf;		/* original dhBuffer */
	char *	 sftXbuf;		/* alternate buffer to save previous
					      record read for evaluating
					      group breaks */
	char *	 sftP;			/* pointer to table name in statement */
};
typedef struct _frmtbl  FRMTBL;

struct _structmap {
	char *	mapOld;			/* pointer into original structure */
	char *	mapNew;			/* pointer to corresponding new
					      structure */
};
typedef struct _structmap  STRUCTMAP;

struct _fldlist {
	SFIELD	sflFld;			/* field name */
	short	sflFlag;		/* ORDER BY:  0 = original ORDER BY
					              1 = from GROUP BY
					   GROUP BY:  1 = in SELECT list
						      2 = in ORDER BY
						      3 = in neither */
	short	sflSortord;		/* sort order (ORDER BY only)
					      1 ascending, -1 descending */
	VALUE   sflGrpval;		/* previous row value for group
					      break logic */
	short	sflInidx;		/* in index */
	EXPR *	sflSelexp;		/* SELECT list expression referenced
					      by sort field */
	struct _fldlist *sflNxt;	/* next field of field list */
	struct _fldlist *sflAltlist;	/* any alternative flds for ORDER BY */
	struct _fldlist *sflCurfld;	/* the current of the
					      primary/alternative fields */
	char *	sflP;			/* pointer to field name in statement */
};
typedef struct _fldlist  FLDLIST;

/* Structures used to determine access order of FROM tables
 *    based on join indices.
 */
struct _bfctlst {
	BFACTOR * sfsFact;		/* boolean factor in a list */
	short	  sfsWeight;		/* optimization weighting (1 = best) */
	struct _bfctlst *sfsNext;	/* next item of the factor list */
};
typedef struct _bfctlst  BFACTLST;

struct _ordfld {
	DBFIELD * sofFptr;		/* database field pointer */
	short	  sofSortord;		/* sort order: 1 ascending,
						      -1 descending */
	short	  sofReqidx;		/* index required for ORDER BY */
	short	  sofIdxcand;		/* candidate for ORDER BY index */
	BFACTLST *sofFldfacts;		/* boolean factor list for each field */
	BFACTLST *sofCurfact;		/* current item of the factor list */
	struct _ordfld *sofCurfld;	/* current item of ORDER BY fld. list */
	struct _ordfld *sofNext;	/* next item of ORDER BY field list */
};
typedef struct _ordfld ORDFLD;

struct _joinlst {
	ORDFLD *  sjlOrdfld;		/* pointer to ORDER BY field struct. */
	struct _joinlst *sjlNext;	/* next item of join field list */
};
typedef struct _joinlst  JOINLIST;

struct _S_TBLORD {
	FRMTBL *  stoFrmtbl;		/* pointer to FRMTBL structure */
	ORDFLD    stoOrdflds[NPARTS];	/* fields of ORDER BY clause */
	BFACTOR * stoEqfacts[NPARTS];	/* boolean factors of fields equal to
					      constants, fields to be merged
					      with ORDER BY fields */
	JOINLIST  stoJoin[NPARTS];	/* list of ORDER BY field joins for each
					      field */
	short	  stoNumflds;		/* number of index field candidates */
	short	  stoNumeqfacts;	/* number of constant equality factors*/
	short	  stoPhase;		/* index evaluation phase */
	long	  stoTblsiz;		/* size of table in bytes */
};
typedef struct _S_TBLORD  TBLORD;

struct _bterm {
	BFACTOR	*sbtFact;		/* left boolean factor */
					/* AND */
	struct _bterm *	sbtRtrm;	/* right boolean term */
	short	 sbtObjoin;		/* candidate for ORDER BY join */
	short	 sbtSubqalloc;		/* allocated for subquery join factor */
};
typedef struct _bterm  BTERM;

struct _cond {
	short	scnAlways;		/* 0=always false, 1=always true
					       -1=undefined */
	BTERM	scnTerm;		/* left boolean term */
					/* OR */
	struct _cond *	scnRcond;	/* right condition */
	short	scnSubqalloc;		/* allocated for subquery join factor */
};
typedef struct _cond  COND;

struct _select {
	short	 selNum;	  /* SELECT structure number */
	short	 selUniq;	  /* no duplicate results */
	short	 selAll;	  /* SELECT * */
	EXPR	 selExp;	  /* initial expression of select list tuple */
	FRMTBL * selFtp;	  /* FROM table list */
	short	 selNtbls;	  /* number of tables in FROM table list;
					0 = not yet ordered */
	COND *	 selWcond;	  /* where condition */
	FLDLIST *selGlst;	  /* fields to group by */
	COND *	 selHcond;	  /* having condition */
	FLDLIST *selSortflds;	  /* ORDER BY fields */
	short	 selDblsort;	  /* GROUP and ORDER BY use different indices */
	struct _select *selOuter; /* outer select, if this is a nested select */
	long	 selUniqcnt;	  /* counter for COUNT (UNIQUE ...) */
	long	 selGrpcnt;	  /* counter for aggregate grouping */
	short	 selGrpauto;	  /* GROUP BY auto-generated for SELECT UNIQUE*/
	char	 selTmpnam[TBLNAMSIZ+1];	/* INTO TEMP table name */
	short	 selNologtmp;	  /* no transaction logging for INTO TEMP? */
	DBHEAD * selIntotmptp;	  /* INTO TEMP table DBHEAD pointer */
	DBHEAD * selTmptp;	  /* temporary table DBHEAD pointer for result
					of SELECT (may be INTO TEMP if another
					temp table not needed for sorting) */
	DBHEAD * selTmpgrptp;	  /* temporary table DBHEAD pointer for
					GROUP BY result */
	short	 selForupdate;	  /* FOR UPDATE clause used */
	DBHEAD * selUpdtp;	  /* table structure for UPDATEd table */
	short	 selUpdidx;	  /* update index of access? */
	_SQCURSOR *selCursforupd; /* Cursor with FOR UPDATE
					(pointed to by UPDATE statement) */
	LISTV *  selPrvvals;	  /* if nested select, previous index value */
	short	 selResprv;	  /* if nested select, previous result (0/1) */
	short	 selFmstartmd;    /* mode argument for fmstart() */
	short    selFirstreadflg; /* first read flag */
	long	 selCurrow;	  /* output row number read
					0 - none read or ISPREV from first
					> last - ISNEXT from last */
	short	 selCorrelated;	  /* correlated subquery? */
	short	 selMaxoutgrp;	  /* maximum OUTER join group number
					0 = none */
	short	 selHasbrack;	  /* SELECT has reduction criteria? */
	struct _select *selOrigsel;  /* Original select if building a temp table
					has caused SELECT to be restructured */
	struct sqlda *selQdesc;	  /* sqlda structure for subquery
					(only used with a single row result) */
};
typedef struct _select  SELECT;

/* Fields added/modified to by INSERT/UPDATE clause.
 */
struct _sqlfield {
	char	 sqfFldnam[FLDNAMSIZ+1]; /* field name */
	DBFIELD *sqfFptr;		 /* pointer to table field structure */
	VALUE    sqfVal;		 /* value to be assigned to field */
	short    sqfQt;			 /* is value quoted? */
	short	 sqfDecs;		 /* number of digits right of decimal */
	SELECT * sqfSetsel;		 /* SELECT for an UPDATE ... SET */
	struct _sqlfield *sqfNext;	 /* next field */
	char *   sqfFldp;		 /* ptr. to field name in statement */
	char *   sqfValp;		 /* ptr. to value in statement */
};
typedef struct _sqlfield  SQLFIELD;

/* Header structure for INSERT or UPDATE statement.
 */
struct _sqltbl {
	char	 sqtTnam[TBLNAMSIZ+1];	  /* table name */
	char	 sqtTowner[USERNAMSIZ+1]; /* table owner name */
	DBHEAD * sqtTptr;		  /* pointer to table header structure;
					        for UPDATE, additional table
					        header structure if UPDATEd
					        field(s) is part of index of
					        access */
	SQLFIELD sqtFlds;		  /* any associated fields */
	char	 sqtIdxnam[IDXNAMSIZ+1];  /* index name */
	char	 sqtIowner[USERNAMSIZ+1]; /* index owner name */
	DBINDEX *sqtIptr;		  /* pointer to index structure */
	short	 sqtAllflds;		  /* UPDATE ... SET * */
	long	 sqtSerialno;		  /* serial number */
	short	 sqtNflds;		  /* number of associated fields */
	short	 sqtFlag;		  /* all purpose flag */
};
typedef struct _sqltbl SQLTBL;

struct _hostv {
	VALUE 	  hvlVal;	  /* VALUE of host variable */
	EXPR *	  hvlExp;	  /* expression that contains '?'
				        (WHERE or UPDATE ... SET) */
	SQLFIELD *hvlInsmodf;	  /* pointer to INSERT field */
	struct _hostv *	hvlNext;  /* next host var. struct. in linked list */
};
typedef struct _hostv  HOSTV;

struct _hosthdr {
	HOSTV   hhdHostvars;	  /* linked list of host vars. VALUE structs. */
	short	hhdHostcnt;	  /* host variables counter */
	short	hhdHostset;	  /* Has the host variable been set?
					(received its value with USING) */
};
typedef struct _hosthdr  HOSTHDR;

/* Structures for allocating and deallocating dynamic memory.
 */
struct _alloclist {
	struct _alloclist *salPrev;
	char *	salMem;
};
typedef struct _alloclist  ALLOCLIST;

struct _selmem {
	ALLOCLIST *sqmParsmem;
	ALLOCLIST *sqmCursmem;
};
typedef struct _selmem  SQLMEM;

#define SBFNULL	(BFACTOR *)0
#define SBKNULL	(VALBRACK *)0
#define SBTNULL	(BTERM *)0
#define SCNNULL	(COND *)0
#define SDFNULL	(DTFUNC *)0
#define SDTNULL	(DTEXPR *)0
#define SDXNULL	(SELINDEX *)0
#define SELNULL	(SELECT *)0
#define SFCNULL	(FACTOR *)0
#define SFLNULL	(FLDLIST *)0
#define SFSNULL	(BFACTLST *)0
#define SFTNULL	(FRMTBL *)0
#define SJLNULL	(JOINLIST *)0
#define SLFNULL	(SFIELD *)0
#define SLVNULL	(LISTV *)0
#define SOFNULL	(ORDFLD *)0
#define SOPNULL	(OPTIMINFO *)0
#define SQMNULL	(SQLMEM *)0
#define SQTNULL	(SQLTBL *)0
#define SSFNULL	(SELFLDS *)0
#define STMNULL	(TERM *)0
#define STONULL	(TBLORD *)0
#define SXPNULL	(EXPR *)0
#define SQFNULL	(SQLFIELD *)0
#define HVLNULL	(HOSTV *)0
#define HHDNULL	(HOSTHDR *)0
#define ALNULL	(ALLOCLIST *)0

/* Is the SELECT expression just 1 field, with no arithmetic or function
 *     or substring starting at a character other than the first?
 */
#define is1fldexp(e)	((e) != SXPNULL && \
			 (e)->sxpRexp == SXPNULL && \
			 (e)->sxpTerm.stmRtrm == STMNULL && \
			 (e)->sxpTerm.stmFact.sfcEtype == SGLFIELD && \
			 ((e)->sxpTerm.stmFact.sfcVal.vlType != CHARTYPE || \
			  ((e)->sxpTerm.stmFact.sfcFld.slfStart <= 1 && \
			   ((e)->sxpTerm.stmFact.sfcFld.slfEnd == 0 || \
			    (e)->sxpTerm.stmFact.sfcFld.slfEnd == \
			    (e)->sxpTerm.stmFact.sfcFld.slfFptr->dfBytes))))

#define getexpfld(e)	 (&(e)->sxpTerm.stmFact.sfcFld)
#define getevtlen(e)	 getvtlen( (e)->sxpType, (int) (e)->sxpSiz, (int) (e)->sxpOffs)
#define setfldincls(f,c) ((f)->ssfClausin |= (1 << c))
#define isfldincls(f,c)	 ((f)->ssfClausin & (1 << c))
#define isidchar(c)	 (isalnum( c) || c == '_')
#define stdputs(f,s)	 write( f, s, (unsigned) strlen( s))

/* in 'sql/globals.c' */
M_TLS extern short waitmode;
M_TLS extern short interact;
M_TLS extern short prwarn;
M_TLS extern short firstwarn;
M_TLS extern char userpriv;
M_TLS extern char progname[];
M_TLS extern int squse0fornull;
M_TLS extern short selcnt;
M_TLS extern int
#ifdef ANSIPROTO
(*sqlsigfunc)( void);
#else
(*sqlsigfunc)();
#endif
/* no M_TLS -- read only structures */
extern char *boolops[];
extern char *datetypes[];

#ifdef TRACE
M_TLS extern int explrwfd;
#endif

#endif /* SQLFX_N */
