/* ekpsel.f -- translated by f2c (version 19980913).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/

#include "f2c.h"

/* Table of constant values */

static integer c__27869 = 27869;
static integer c__100 = 100;

/* $Procedure  EKPSEL ( EK, parse SELECT clause ) */
/* Subroutine */ int ekpsel_(char *query, integer *n, integer *xbegs, integer 
	*xends, char *xtypes, char *xclass, char *tabs, char *cols, logical *
	error, char *errmsg, ftnlen query_len, ftnlen xtypes_len, ftnlen 
	xclass_len, ftnlen tabs_len, ftnlen cols_len, ftnlen errmsg_len)
{
    /* Initialized data */

    static char chrtyp[4*4] = "CHR " "DP  " "INT " "TIME";

    /* System generated locals */
    integer i__1, i__2;

    /* Builtin functions */
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
    integer s_rnge(char *, integer, char *, integer);

    /* Local variables */
    char qtab[64];
    extern /* Subroutine */ int zzekencd_(char *, integer *, char *, 
	    doublereal *, logical *, char *, integer *, ftnlen, ftnlen, 
	    ftnlen), zzekqtab_(integer *, char *, integer *, char *, char *, 
	    ftnlen, ftnlen, ftnlen), zzekqini_(integer *, integer *, integer *
	    , char *, doublereal *, ftnlen), zzekreqi_(integer *, char *, 
	    integer *, ftnlen), zzekqsel_(integer *, char *, integer *, 
	    integer *, integer *, char *, integer *, char *, integer *, 
	    ftnlen, ftnlen, ftnlen);
    integer i__;
    extern /* Subroutine */ int ekcii_(char *, integer *, char *, integer *, 
	    ftnlen, ftnlen), chkin_(char *, ftnlen);
    char eqryc[2000];
    doublereal eqryd[100];
    integer eqryi[27875];
    extern logical return_(void);
    char aka[64], column[32];
    integer attdsc[6], colidx, errptr, tabidx;
    extern /* Subroutine */ int chkout_(char *, ftnlen);

/* $ Abstract */

/*     Parse the SELECT clause of an EK query, returning full particulars */
/*     concerning each selected item. */

/* $ Copyright */

/*     Copyright (1995), California Institute of Technology. */
/*     U.S. Government sponsorship acknowledged. */

/* $ Required_Reading */

/*     None. */

/* $ Keywords */

/*     PRIVATE */

/* $ Declarations */

/*     Include Section:  EK Column Attribute Descriptor Parameters */

/*        ekattdsc.inc Version 1    23-AUG-1995 (NJB) */


/*     This include file declares parameters used in EK column */
/*     attribute descriptors.  Column attribute descriptors are */
/*     a simplified version of column descriptors:  attribute */
/*     descriptors describe attributes of a column but do not contain */
/*     addresses or pointers. */


/*     Size of column attribute descriptor */


/*     Indices of various pieces of attribute descriptors: */


/*     ATTSIZ is the index of the column's class code.  (We use the */
/*     word `class' to distinguish this item from the column's data */
/*     type.) */


/*     ATTTYP is the index of the column's data type code (CHR, INT, DP, */
/*     or TIME).  The type is actually implied by the class, but it */
/*     will frequently be convenient to look up the type directly. */



/*     ATTLEN is the index of the column's string length value, if the */
/*     column has character type.  A value of IFALSE in this element of */
/*     the descriptor indicates that the strings have variable length. */


/*     ATTSIZ is the index of the column's element size value.  This */
/*     descriptor element is meaningful for columns with fixed-size */
/*     entries.  For variable-sized columns, this value is IFALSE. */


/*     ATTIDX is the location of a flag that indicates whether the column */
/*     is indexed.  The flag takes the value ITRUE if the column is */
/*     indexed and otherwise takes the value IFALSE. */


/*     ATTNFL is the index of a flag indicating whether nulls are */
/*     permitted in the column.  The value at location NFLIDX is */
/*     ITRUE if nulls are permitted and IFALSE otherwise. */


/*     End Include Section:  EK Column Attribute Descriptor Parameters */


/*     Include Section:  EK Column Name Size */

/*        ekcnamsz.inc Version 1    17-JAN-1995 (NJB) */


/*     Size of column name, in characters. */


/*     End Include Section:  EK Column Name Size */


/*     Include Section:  EK Query Limit Parameters */

/*        ekqlimit.inc  Version 3    16-NOV-1995 (NJB) */

/*           Parameter MAXCON increased to 1000. */

/*        ekqlimit.inc  Version 2    01-AUG-1995 (NJB) */

/*           Updated to support SELECT clause. */


/*        ekqlimit.inc  Version 1    07-FEB-1995 (NJB) */


/*     These limits apply to character string queries input to the */
/*     EK scanner.  This limits are part of the EK system's user */
/*     interface:  the values should be advertised in the EK required */
/*     reading document. */


/*     Maximum length of an input query:  MAXQRY.  This value is */
/*     currently set to twenty-five 80-character lines. */


/*     Maximum number of columns that may be listed in the */
/*     `order-by clause' of a query:  MAXSEL.  MAXSEL = 50. */


/*     Maximum number of tables that may be listed in the `FROM */
/*     clause' of a query: MAXTAB. */


/*     Maximum number of relational expressions that may be listed */
/*     in the `constraint clause' of a query: MAXCON. */

/*     This limit applies to a query when it is represented in */
/*     `normalized form': that is, the constraints have been */
/*     expressed as a disjunction of conjunctions of relational */
/*     expressions. The number of relational expressions in a query */
/*     that has been expanded in this fashion may be greater than */
/*     the number of relations in the query as orginally written. */
/*     For example, the expression */

/*             ( ( A LT 1 ) OR ( B GT 2 ) ) */
/*        AND */
/*             ( ( C NE 3 ) OR ( D EQ 4 ) ) */

/*     which contains 4 relational expressions, expands to the */
/*     equivalent normalized constraint */

/*             (  ( A LT 1 ) AND ( C NE 3 )  ) */
/*        OR */
/*             (  ( A LT 1 ) AND ( D EQ 4 )  ) */
/*        OR */
/*             (  ( B GT 2 ) AND ( C NE 3 )  ) */
/*        OR */
/*             (  ( B GT 2 ) AND ( D EQ 4 )  ) */

/*     which contains eight relational expressions. */



/*     MXJOIN is the maximum number of tables that can be joined. */


/*     MXJCON is the maximum number of join constraints allowed. */


/*     Maximum number of order-by columns that may be used in the */
/*     `order-by clause' of a query: MAXORD. MAXORD = 10. */


/*     Maximum number of tokens in a query: 500. Tokens are reserved */
/*     words, column names, parentheses, and values. Literal strings */
/*     and time values count as single tokens. */


/*     Maximum number of numeric tokens in a query: */


/*     Maximum total length of character tokens in a query: */


/*     Maximum length of literal string values allowed in queries: */
/*     MAXSTR. */


/*     End Include Section:  EK Query Limit Parameters */


/*     Include Section:  EK Encoded Query Internal Parameters */

/*        ekquery.inc  Version 3    16-NOV-1995 (NJB) */

/*           Updated to reflect increased value of MAXCON in */
/*           ekqlimit.inc. */

/*        ekquery.inc  Version 2    03-AUG-1995 (NJB) */

/*           Updated to support representation of the SELECT clause. */


/*        ekquery.inc  Version 1    12-JAN-1995 (NJB) */


/*     An encoded EK query is an abstract data type implemented */
/*     as an integer cell, along with a double precision cell and */
/*     a character string.  The d.p. cell and string contain numeric */
/*     and string values from the query string represented by the */
/*     encoded query. */

/*     The parameters in this file are intended for use only by the */
/*     EK encoded query access routines.  Callers of EK routines should */
/*     not use these parameters. */

/*     The following parameters are indices of specified elements */
/*     in the integer portion of the encoded query. */

/*     Encoded query architecture type: */


/*     `Name resolution' consists of: */

/*        - Verifying existence of tables:  any table names listed */
/*          in the FROM clause of a query must be loaded. */

/*        - Validating table aliases used to qualify column names. */

/*        - Verifying existence of columns and obtaining data types */
/*          for columns. */

/*        - Setting data type codes for literal values in the encoded */
/*          query. */

/*        - Checking consistency of operators and operand data types. */

/*        - Making sure unqualified column names are unambiguous. */

/*        - For constraints, mapping the table names used to qualify */
/*          column names to the ordinal position in the FROM clause */
/*          of the corresponding table. */


/*     Initialization status---this flag indicates whether the encoded */
/*     query has been initialized.  Values are ITRUE or IFALSE.  See the */
/*     include file ekbool.inc for parameter values. */


/*     Parse status---this flag indicates whether the parsing operation */
/*     that produced an encoded query has been completed. Values are */
/*     ITRUE or IFALSE. */


/*     Name resolution status---this flag indicates whether names */
/*     have been resolved in an encoded query.  Values are ITRUE or */
/*     IFALSE. */


/*     Time resolution status---this flag indicates whether time values */
/*     have been resolved in an encoded query.  Time resolution */
/*     consists of converting strings representing time values to ET. */
/*     Values of the status are ITRUE or IFALSE. */


/*     Semantic check status---this flag indicates whether semantic */
/*     checking of constraints has been performed. */


/*     Number of tables specified in FROM clause: */


/*     Number of constraints in query: */


/*     A special value is used to indicate the `maximal' constraint--- */
/*     one that logically cannot be satisfied.  If the constraints */
/*     are equivalent to the maximal constraint, the location EQNCNS */
/*     is assigned the value EQMXML */


/*     Number of constraint conjunctions: */


/*     Number of order-by columns: */


/*     Number of SELECT columns: */


/*     Size of double precision buffer: */


/*     `Free' pointer into double precision buffer: */


/*     Size of character string buffer: */


/*     `Free' pointer into character string buffer: */


/*     The following four base pointers will be valid after a query */
/*     has been parsed: */

/*     Base pointer for SELECT column descriptors: */


/*     Base pointer for constraint descriptors: */


/*     Base pointer for conjunction sizes: */


/*     Base pointer for order-by column descriptors: */


/*     After the quantities named above, the integer array contains */
/*     series of descriptors for tables, constraints, and order-by */
/*     columns, as well as a list of `conjunction sizes'---that is, */
/*     the sizes of the groups of constraints that form conjunctions, */
/*     after the input query has been re-arranged as a disjunction of */
/*     conjunctions of constraints. */


/*     The offsets of specific elements within descriptors are */
/*     parameterized. The base addresses of the descriptors themselves */
/*     must be  calculated using the counts and sizes of the items */
/*     preceding them. */

/*     A diagram of the structure of the variable-size portion of the */
/*     integer array is shown below: */


/*        +-------------------------------------+ */
/*        | Fixed-size portion of encoded query | */
/*        +-------------------------------------+ */
/*        |         Encoded FROM clause         | */
/*        +-------------------------------------+ */
/*        |      Encoded constraint clause      | */
/*        +-------------------------------------+ */
/*        |          Conjunction sizes          | */
/*        +-------------------------------------+ */
/*        |       Encoded ORDER BY clause       | */
/*        +-------------------------------------+ */
/*        |        Encoded SELECT clause        | */
/*        +-------------------------------------+ */


/*     Value Descriptors */
/*     ---------------- */

/*     In order to discuss the various descriptors below, we'll make use */
/*     of sub-structures called `value descriptors'.  These descriptors */
/*     come in two flavors:  character and double precision.  For */
/*     strings, a descriptor is a set of begin and end pointers that */
/*     indicate the location of the string in the character portion of an */
/*     encoded query, along with the begin and end pointers for the */
/*     corresponding lexeme in the original query.  The pointers are set */
/*     to zero when they are not in use, for example if they refer to an */
/*     optional lexeme that did not appear in the input query. */

/*     All value descriptors start with a data type indicator; values */
/*     are from ektype.inc.  Integer and time values are referred to */
/*     by double precision descriptors. */

/*     Parameters for string value descriptor elements: */


/*     Numeric value descriptors are similar to those for string values, */
/*     the difference being that they have only one pointer to the value */
/*     they represent.  This pointer is the index of the value in the */
/*     encoded query's numeric buffer. */


/*     All value descriptors have the same size.  In order to allow */
/*     table descriptors to have the same size as value descriptors, */
/*     we include an extra element in the descriptor. */


/*     Column Descriptors */
/*     ----------------- */

/*     Each column descriptor consists of a character descriptor for the */
/*     name of the column, followed by an index, which gives the ordinal */
/*     position of the column in the logical table to which the column */
/*     belongs.  The index element is filled in during name resolution. */


/*     Table Descriptors */
/*     ----------------- */

/*     Each table descriptor consists of a character descriptor for the */
/*     name of the table, followed by an index, which gives the ordinal */
/*     position of the table in the FROM clause in the original query. */
/*     The index element is filled in during name resolution.  Aliases */
/*     and table names have identical descriptor structures. */


/*     Constraint descriptors */
/*     ------------------ */

/*     Each constraint is characterized by: */

/*        - A code indicating whether the constraint compares values */
/*          in two columns or the value in a column and a literal */
/*          value.  The values of this element are EQCOL and EQVAL. */



/*        - A descriptor for the table used to qualify the */
/*          column name on the left side of the constraint. */


/*        - A character value descriptor for the column name on the left */
/*          side of the query. */


/*        - An operator code indicating the relational operator used */
/*          in the constraint. */


/*        If the constraint compares values from two columns, the */
/*        next items are table and column name descriptors that apply to */
/*        the column named on the right side of the relational operator. */


/*        If the constraint has a literal value on the right side, the */
/*        operator code is followed by... */

/*        - a value descriptor. */


/*        - Size of a constraint descriptor: */


/*     Conjunction sizes */
/*     ----------------- */

/*     The size of each conjunction of constraints occupies a single */
/*     integer. */




/*     Order-by Column Descriptors */
/*     --------------------------- */

/*     Each order-by column descriptor contains descriptors for */
/*     the table containing the column and for the name of the column */
/*     itself; one additional element is used to indicate the direction */
/*     of the ordering (ascending vs descending). */


/*        - The last integer in the descriptor indicates whether the */
/*          order direction is ascending or descending. */


/*        - Size of an order-by column descriptor: */


/*     Codes indicating sense of ordering (ascending vs descending): */


/*     SELECT Column Descriptors */
/*     --------------------------- */

/*     Each SELECT column descriptor contains descriptors for */
/*     the table containing the column and for the name of the column */
/*     itself. */


/*        - Size of a SELECT column descriptor: */


/*     Miscellaneous parameters: */


/*     EQIMIN is the minimum size of the integer portion of */
/*     an encoded query.  EQIMIN depends on the parameters */

/*        MAXTAB */
/*        MAXCON */
/*        MAXORD */
/*        MAXSEL */

/*     all of which are declared in the include file ekqlimit.inc. */
/*     The functional definition of EQIMIN is: */

/*     INTEGER               EQIMIN */
/*     PARAMETER           ( EQIMIN =   EQVBAS */
/*    .                              +  MAXTAB * EQVDSZ * 2 */
/*    .                              +  MAXCON * EQCDSZ */
/*    .                              +  MAXCON */
/*    .                              +  MAXORD * EQODSZ */
/*    .                              +  MAXSEL * EQSDSZ     ) */


/*     End Include Section:  EK Encoded Query Internal Parameters */


/*     Include Section:  EK Table Name Size */

/*        ektnamsz.inc Version 1    17-JAN-1995 (NJB) */


/*     Size of table name, in characters. */


/*     End Include Section:  EK Table Name Size */


/*     Include Section:  EK Data Types */

/*        ektype.inc Version 1  27-DEC-1994 (NJB) */


/*     Within the EK system, data types of EK column contents are */
/*     represented by integer codes.  The codes and their meanings */
/*     are listed below. */

/*     Integer codes are also used within the DAS system to indicate */
/*     data types; the EK system makes no assumptions about compatibility */
/*     between the codes used here and those used in the DAS system. */


/*     Character type: */


/*     Double precision type: */


/*     Integer type: */


/*     `Time' type: */

/*     Within the EK system, time values are represented as ephemeris */
/*     seconds past J2000 (TDB), and double precision numbers are used */
/*     to store these values.  However, since time values require special */
/*     treatment both on input and output, and since the `TIME' column */
/*     has a special role in the EK specification and code, time values */
/*     are identified as a type distinct from double precision numbers. */


/*     End Include Section:  EK Data Types */

/* $ Brief_I/O */

/*     Variable  I/O  Description */
/*     --------  ---  -------------------------------------------------- */
/*     QUERY      I   EK query. */
/*     N          O   Number of items in SELECT clause of query. */
/*     XBEGS      O   Begin positions of expressions in SELECT clause. */
/*     XENDS      O   End positions of expressions in SELECT clause. */
/*     XTYPES     O   Data types of expressions. */
/*     XCLASS     O   Classes of expressions. */
/*     TABS       O   Names of tables qualifying SELECT columns. */
/*     COLS       O   Names of columns in SELECT clause of query. */
/*     ERROR      O   Error flag. */
/*     ERRMSG     O   Parse error message. */

/* $ Detailed_Input */

/*     QUERY          is a character string containing an EK query. */
/*                    EK queries have the general form */

/*                       SELECT <select expr>, <select expr>, ... */
/*                       FROM <table spec>, <table spec>, ... */
/*                       [WHERE <constraint list>] */
/*                       [ORDER BY <order-by column list>] */

/*                    Here the symbol <select expr> indicates any */
/*                    expression representing an entity that can be */
/*                    selected.  Commonly, the selected items are */
/*                    columns, with or without qualifying table names, */
/*                    having the form */

/*                       <column name> */
/*                       <table name>.<column name> */
/*                       <table alias>.<column name> */

/*                    but more general expressions may also be selected. */
/*                    Examples are functions, such as */

/*                       COUNT(*) */
/*                       COUNT( <table name>.<column name> ) */
/*                       MAX  ( <table name>.<column name> ) */

/*                    or expressions involving constants, such as */

/*                       2 * <column name> */

/* $ Detailed_Output */

/*     N              is the number of items specified in the */
/*                    SELECT clause of the input query. */

/*     XBEGS, */
/*     XENDS          are, respectively, arrays of begin and end */
/*                    positions of expressions designating items in the */
/*                    SELECT clause of the input query.  The Ith */
/*                    expression is located in the substring */

/*                       QUERY ( XBEGS(I) : XENDS(I) ) */


/*     XTYPES         is an array of short strings indicating the data */
/*                    types of the expressions in the SELECT clause. */
/*                    Values and meanings of XTYPES are: */

/*                       'CHR'        Character type */
/*                       'DP'         Double precision type */
/*                       'INT'        Integer type */
/*                       'TIME'       Time type */

/*                    The Ith element of XTYPES refers to the Ith */
/*                    selected item. */

/*                    The data type of an expression indicates which */
/*                    fetch routine to use to obtain values of the */
/*                    selected expression.  The mapping of data types */
/*                    to fetch routines is shown below: */

/*                       'CHR'        EKGC */
/*                       'DP'         EKGD */
/*                       'INT'        EKGI */
/*                       'TIME'       EKGD */

/*                    Note that time values are stored as d.p. numbers. */


/*     XCLASS         is an array of short strings giving the classes */
/*                    of the expressions occurring in the SELECT clause */
/*                    of the input query.  Values and meanings of */
/*                    XCLASS are: */

/*                       'COL'        Selected item was a column.  The */
/*                                    column may qualified. */

/*                       'FUNC'       Selected item was a simple */
/*                                        function invocation of the form */

/*                                           F ( <column> ) */

/*                                        or else was */

/*                                           COUNT(*) */

/*                       'EXPR'       Selected item was a more general */
/*                                    expression than those shown above. */

/*                    The Ith element of XCLASS refers to the Ith */
/*                    selected item. */

/*                    When a selected item is a column, the values of */
/*                    the arguments TABS and COLS (discussed below) are */
/*                    defined. */


/*     TABS           is an array of names of tables corresponding to */
/*                    the columns in the SELECT clause.  The Ith element */
/*                    of TABS corresponds to the table containing the */
/*                    Ith SELECT column.  Table names returned in TABS */
/*                    are the actual names of tables in loaded EK, not */
/*                    aliases supplied in the input query.  Table names */
/*                    are supplied even if the corresponding column was */
/*                    unqualified in the input query, as long as the */
/*                    column name was unambiguous. */

/*                    The contents of TABS(I) are defined if and only if */
/*                    the returned value of XCLASS(I) is 'COL'. */


/*     COLS           is an array containing the columns of the SELECT */
/*                    clause.  The contents of COLS(I) are defined if and */
/*                    only if the returned value of XCLASS(I) is 'COL'. */


/*     ERROR          is a logical flag indicating whether the input */
/*                    QUERY parsed correctly.  The other outputs of this */
/*                    routine, except for ERRMSG, are undefined if a */
/*                    parse error occurred.  ERROR is returned .TRUE. if */
/*                    a parse error occurred, .FALSE. otherwise. */

/*     ERRMSG         is a character string describing the cause of a */
/*                    parse error, if such an error occurred.  Otherwise, */
/*                    ERRMSG is returned blank. */

/* $ Parameters */

/*     None. */

/* $ Exceptions */

/*     1)  Parse failures do not cause this routine to signal errors; */
/*         instead, the ERROR and ERRMSG outputs indicate invalid */
/*         QUERIES. */

/*     2)  Queries cannot be parsed correctly unless at least one EK */
/*         is loaded. */

/* $ Files */

/*     None. */

/* $ Particulars */

/*     This routine allows callers of the EK fetch routines to determine */
/*     at run time the attributes of the columns from which data is to be */
/*     fetched. */

/* $ Examples */

/*     1)  Use of EKPSEL to assist in fetching rows matching queries */
/*         supplied at run time. */

/*         The code fragment shown here does not rely on advance */
/*         knowledge of the input query or the contents of any loaded EK */
/*         files. */

/*         To simplify the example, we assume that all data is scalar. */

/*            C */
/*            C     Prompt for query.  Parse the SELECT clause using */
/*            C     EKPSEL. */
/*            C */
/*                  CALL PROMPT ( 'Enter query > ', QUERY ) */

/*                  CALL EKPSEL ( QUERY, */
/*                                N, */
/*                                XBEGS, */
/*                                XENDS, */
/*                                XBEGS, */
/*                                XTYPES, */
/*                                XCLASS, */
/*                                TABS, */
/*                                COLS, */
/*                                ERROR, */
/*                                ERRMSG ) */


/*                  IF ( ERROR ) THEN */

/*                     WRITE (*,*) ERRMSG */

/*                  ELSE */
/*            C */
/*            C        Submit query to the EK query system. */
/*            C */
/*                     CALL EKFIND ( QUERY, NMROWS, ERROR, ERRMSG ) */

/*                     IF ( ERROR ) THEN */

/*                        WRITE (*,*) ERRMSG */

/*                     ELSE */
/*            C */
/*            C           Fetch the rows that matched the query. */
/*            C */
/*                        DO ROW = 1, NMROWS */
/*            C */
/*            C              Fetch data from the Ith row. */
/*            C */
/*                           WRITE (*,*) ' ' */
/*                           WRITE (*,*) 'ROW = ', ROW */

/*                           DO COL = 1, N */
/*            C */
/*            C                 Fetch the data from the Jth selected */
/*            C                 column. */
/*            C */
/*                              IF ( XCLASS(COL) .EQ. 'COL' ) THEN */

/*                                 OUTSTR  =  COLS(COL) */
/*                                 CALL PREFIX ( '.',       0, OUTSTR ) */
/*                                 CALL PREFIX ( TABS(COL), 0, OUTSTR ) */
/*                                 WRITE (*,*) 'COLUMN = ', OUTSTR */

/*                              ELSE */

/*                                 B  =  XBEGS(COL) */
/*                                 E  =  XENDS(COL) */
/*                                 WRITE (*,*) 'ITEM = ', QUERY(B:E) */

/*                              END IF */

/*                              IF ( XTYPES(COL) .EQ. 'CHR' ) THEN */

/*                                 CALL EKGC ( COL,   ROW,   1, */
/*                 .                           CDATA, NULL,  FOUND ) */

/*                                 IF ( NULL ) THEN */
/*                                    WRITE (*,*) '<Null>' */
/*                                 ELSE */
/*                                    WRITE (*,*) CDATA */
/*                                 END IF */


/*                              ELSE IF ( XTYPES(COL) .EQ. 'DP' ) THEN */

/*                                 CALL EKGD ( COL,   ROW,   1, */
/*                 .                           DDATA, NULL,  FOUND ) */

/*                                 IF ( NULL ) THEN */
/*                                    WRITE (*,*) '<Null>' */
/*                                 ELSE */
/*                                    WRITE (*,*) DDATA */
/*                                 END IF */


/*                              ELSE IF ( XTYPES(COL) .EQ. 'INT' ) THEN */

/*                                 CALL EKGI ( COL,   ROW,   1, */
/*                 .                           IDATA, NULL,  FOUND ) */

/*                                 IF ( NULL ) THEN */
/*                                    WRITE (*,*) '<Null>' */
/*                                 ELSE */
/*                                    WRITE (*,*) IDATA */
/*                                 END IF */


/*                              ELSE */
/*            C */
/*            C                    The item is a time value.  Convert it */
/*            C                    to UTC for output. */
/*            C */
/*                                 CALL EKGD   ( COL,   ROW,   1, */
/*                 .                             TDATA, NULL,  FOUND ) */

/*                                 IF ( NULL ) THEN */
/*                                    WRITE (*,*) '<Null>' */
/*                                 ELSE */
/*                                    CALL ET2UTC ( TDATA, 'C', 3, UTC ) */
/*                                    WRITE (*,*) UTC */
/*                                 END IF */

/*                              END IF */

/*                           END DO */
/*            C */
/*            C              We're done with the column having index COL. */
/*            C */
/*                        END DO */
/*            C */
/*            C           We're done with the row having index ROW. */
/*            C */
/*                     END IF */
/*            C */
/*            C        We either processed the query or had an error. */
/*            C */
/*                  END IF */
/*            C */
/*            C     We either parsed the SELECT clause or had an error. */
/*            C */


/* $ Restrictions */

/*     1)  Currently, column names are the only supported expressions. */

/* $ Literature_References */

/*     None. */

/* $ Author_and_Institution */

/*     N.J. Bachman       (JPL) */

/* $ Version */

/* -    Beta Version 1.0.0, 19-DEC-1995 (NJB) */

/* -& */
/* $ Index_Entries */

/*     parse select clause of EK query */

/* -& */

/*     SPICELIB functions */


/*     Local parameters */


/*     Local variables */


/*     Saved values */


/*     Initial values */


/*     Standard SPICE error handling. */

    if (return_()) {
	return 0;
    } else {
	chkin_("EKPSEL", (ftnlen)6);
    }

/*     Initialize the encoded query each time, for safety. */

    zzekqini_(&c__27869, &c__100, eqryi, eqryc, eqryd, (ftnlen)2000);

/*     Encode the input query. */

    zzekencd_(query, eqryi, eqryc, eqryd, error, errmsg, &errptr, query_len, (
	    ftnlen)2000, errmsg_len);
    if (*error) {
	chkout_("EKPSEL", (ftnlen)6);
	return 0;
    }

/*     Look up the number of SELECT columns.  For each column, look up */
/*     the parent table, the alias, and the column's name. */

    zzekreqi_(eqryi, "NUM_SELECT_COLS", n, (ftnlen)15);
    i__1 = *n;
    for (i__ = 1; i__ <= i__1; ++i__) {
	zzekqsel_(eqryi, eqryc, &i__, &xbegs[i__ - 1], &xends[i__ - 1], qtab, 
		&tabidx, cols + (i__ - 1) * cols_len, &colidx, (ftnlen)2000, (
		ftnlen)64, cols_len);

/*        Make the table index to the table name. */

	zzekqtab_(eqryi, eqryc, &tabidx, tabs + (i__ - 1) * tabs_len, aka, (
		ftnlen)2000, tabs_len, (ftnlen)64);

/*        Currently, every expression is a column. */

	s_copy(xclass + (i__ - 1) * xclass_len, "COL", xclass_len, (ftnlen)3);

/*        Look up the data type of the column. */

	ekcii_(tabs + (i__ - 1) * tabs_len, &colidx, column, attdsc, tabs_len,
		 (ftnlen)32);
	s_copy(xtypes + (i__ - 1) * xtypes_len, chrtyp + (((i__2 = attdsc[1] 
		- 1) < 4 && 0 <= i__2 ? i__2 : s_rnge("chrtyp", i__2, "ekpse"
		"l_", (ftnlen)478)) << 2), xtypes_len, (ftnlen)4);
    }
    chkout_("EKPSEL", (ftnlen)6);
    return 0;
} /* ekpsel_ */