home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / sql / sqldml.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  121.1 KB  |  3,720 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --txtprt.ada
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. with TEXT_IO;
  5.   use TEXT_IO;
  6.  
  7. package TEXT_PRINT is
  8.  
  9.   type LINE_TYPE is limited private;
  10.  
  11.   type BREAK_TYPE is (BREAK, NO_BREAK);
  12.  
  13.   procedure CREATE_LINE(LINE : in out LINE_TYPE; LENGTH : in POSITIVE);
  14.  
  15.   procedure SET_LINE(LINE : in LINE_TYPE);
  16.  
  17.   function CURRENT_LINE return LINE_TYPE;
  18.  
  19.   procedure SET_INDENT(LINE   : in LINE_TYPE; INDENT : in NATURAL);
  20.   procedure SET_INDENT(INDENT : in NATURAL);
  21.  
  22.   procedure SET_CONTINUATION_INDENT(LINE   : in LINE_TYPE;
  23.                                     INDENT : in INTEGER);
  24.   procedure SET_CONTINUATION_INDENT(INDENT : in INTEGER);
  25.  
  26.   procedure PRINT(FILE : in FILE_TYPE;
  27.                   LINE : in LINE_TYPE;
  28.                   ITEM : in STRING;
  29.                   BRK  : in BREAK_TYPE := BREAK);
  30.   procedure PRINT(FILE : in FILE_TYPE;
  31.                   ITEM : in STRING;
  32.                   BRK  : in BREAK_TYPE := BREAK);
  33.   procedure PRINT(LINE : in LINE_TYPE;
  34.                   ITEM : in STRING;
  35.                   BRK  : in BREAK_TYPE := BREAK);
  36.   procedure PRINT(ITEM : in STRING;
  37.                   BRK  : in BREAK_TYPE := BREAK);
  38.  
  39.   procedure PRINT_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE);
  40.   procedure PRINT_LINE(FILE : in FILE_TYPE);
  41.   procedure PRINT_LINE(LINE : in LINE_TYPE);
  42.   procedure PRINT_LINE;
  43.  
  44.   procedure BLANK_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE);
  45.   procedure BLANK_LINE(FILE : in FILE_TYPE);
  46.   procedure BLANK_LINE(LINE : in LINE_TYPE);
  47.   procedure BLANK_LINE;
  48.  
  49.   generic
  50.     type NUM is range <>;
  51.   package INTEGER_PRINT is
  52.  
  53.     procedure PRINT(FILE : in FILE_TYPE;
  54.                     LINE : in LINE_TYPE;
  55.                     ITEM : in NUM;
  56.                     BRK  : in BREAK_TYPE := BREAK);
  57.     procedure PRINT(FILE : in FILE_TYPE;
  58.                     ITEM : in NUM;
  59.                     BRK  : in BREAK_TYPE := BREAK);
  60.     procedure PRINT(LINE : in LINE_TYPE;
  61.                     ITEM : in NUM;
  62.                     BRK  : in BREAK_TYPE := BREAK);
  63.     procedure PRINT(ITEM : in NUM;
  64.                     BRK  : in BREAK_TYPE := BREAK);
  65.  
  66.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM);
  67.  
  68.   end INTEGER_PRINT;
  69.  
  70.   generic
  71.     type NUM is digits <>;
  72.   package FLOAT_PRINT is
  73.  
  74.     procedure PRINT(FILE : in FILE_TYPE;
  75.                     LINE : in LINE_TYPE;
  76.                     ITEM : in NUM;
  77.                     BRK  : in BREAK_TYPE := BREAK);
  78.     procedure PRINT(FILE : in FILE_TYPE;
  79.                     ITEM : in NUM;
  80.                     BRK  : in BREAK_TYPE := BREAK);
  81.     procedure PRINT(LINE : in LINE_TYPE;
  82.                     ITEM : in NUM;
  83.                     BRK  : in BREAK_TYPE := BREAK);
  84.     procedure PRINT(ITEM : in NUM;
  85.                     BRK  : in BREAK_TYPE := BREAK);
  86.  
  87.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM);
  88.  
  89.   end FLOAT_PRINT;
  90.  
  91.   LAYOUT_ERROR : exception renames TEXT_IO.LAYOUT_ERROR;
  92.  
  93. private
  94.  
  95.   type LINE_REC(LENGTH : INTEGER) is
  96.     record
  97.       USED_YET            : BOOLEAN := FALSE;
  98.       INDENT              : INTEGER := 0;
  99.       CONTINUATION_INDENT : INTEGER := 2;
  100.       BREAK               : INTEGER := 1;
  101.       INDEX               : INTEGER := 1;
  102.       DATA                : STRING(1..LENGTH);
  103.     end record;
  104.  
  105.   type LINE_TYPE is access LINE_REC;
  106.  
  107. end TEXT_PRINT;
  108.  
  109. package body TEXT_PRINT is
  110.  
  111.   DEFAULT_LINE : LINE_TYPE;
  112.  
  113.   procedure CREATE_LINE(LINE : in out LINE_TYPE; LENGTH : in POSITIVE) is
  114.   begin
  115.     LINE := new LINE_REC(LENGTH);
  116.   end CREATE_LINE;
  117.  
  118.   procedure SET_LINE(LINE : in LINE_TYPE) is
  119.   begin
  120.     DEFAULT_LINE := LINE;
  121.   end SET_LINE;
  122.  
  123.   function CURRENT_LINE return LINE_TYPE is
  124.   begin
  125.     return DEFAULT_LINE;
  126.   end CURRENT_LINE;
  127.  
  128.   procedure SET_INDENT(LINE   : in LINE_TYPE; INDENT : in NATURAL) is
  129.   begin
  130.     if INDENT >= LINE.LENGTH then
  131.       raise LAYOUT_ERROR;
  132.     end if;
  133.     if LINE.INDEX = LINE.INDENT + 1 then
  134.       for I in 1..INDENT loop
  135.         LINE.DATA(I) := ' ';
  136.       end loop;
  137.     end if;
  138.     LINE.INDENT := INDENT;
  139.   end SET_INDENT;
  140.  
  141.   procedure SET_INDENT(INDENT : in NATURAL) is
  142.   begin
  143.     SET_INDENT(DEFAULT_LINE,INDENT);
  144.   end SET_INDENT;
  145.  
  146.   procedure SET_CONTINUATION_INDENT(LINE   : in LINE_TYPE;
  147.                                     INDENT : in INTEGER) is
  148.   begin
  149.     if LINE.INDENT + INDENT >= LINE.LENGTH or else LINE.INDENT + INDENT < 0
  150.         then
  151.       raise LAYOUT_ERROR;
  152.     end if;
  153.     LINE.CONTINUATION_INDENT := INDENT;
  154.   end SET_CONTINUATION_INDENT;
  155.  
  156.   procedure SET_CONTINUATION_INDENT(INDENT : in INTEGER) is
  157.   begin
  158.     SET_CONTINUATION_INDENT(DEFAULT_LINE,INDENT);
  159.   end SET_CONTINUATION_INDENT;
  160.  
  161.   procedure PRINT(FILE : in FILE_TYPE;
  162.                   LINE : in LINE_TYPE;
  163.                   ITEM : in STRING;
  164.                   BRK  : BREAK_TYPE := BREAK) is
  165.     NEW_BREAK, NEW_INDEX : INTEGER;
  166.   begin
  167.     if LINE.INDEX + ITEM'LENGTH > LINE.LENGTH + 1 then
  168.       if LINE.INDENT + LINE.CONTINUATION_INDENT + LINE.INDEX - LINE.BREAK +
  169.           ITEM'LENGTH > LINE.LENGTH then
  170.         raise LAYOUT_ERROR;
  171.       end if;
  172.       if ITEM = " " then
  173.         return;
  174.       end if;
  175.       PUT_LINE(FILE,LINE.DATA(1..LINE.BREAK-1));
  176.       for I in 1..LINE.INDENT + LINE.CONTINUATION_INDENT loop
  177.         LINE.DATA(I) := ' ';
  178.       end loop;
  179.       NEW_BREAK := LINE.INDENT + LINE.CONTINUATION_INDENT + 1;
  180.       NEW_INDEX := NEW_BREAK + LINE.INDEX - LINE.BREAK;
  181.       LINE.DATA(NEW_BREAK..NEW_INDEX) := LINE.DATA(LINE.BREAK..LINE.INDEX);
  182.       LINE.BREAK := NEW_BREAK;
  183.       LINE.INDEX := NEW_INDEX;
  184.     end if;
  185.     NEW_INDEX := LINE.INDEX + ITEM'LENGTH;
  186.     LINE.DATA(LINE.INDEX..NEW_INDEX-1) := ITEM;
  187.     LINE.INDEX := NEW_INDEX;
  188.     if BRK = BREAK then
  189.       LINE.BREAK := NEW_INDEX;
  190.     end if;
  191.     LINE.USED_YET := TRUE;
  192.   end PRINT;
  193.  
  194.   procedure PRINT(FILE : in FILE_TYPE;
  195.                   ITEM : in STRING;
  196.                   BRK  : in BREAK_TYPE := BREAK) is
  197.   begin
  198.     PRINT(FILE,DEFAULT_LINE,ITEM,BRK);
  199.   end PRINT;
  200.  
  201.   procedure PRINT(LINE : in LINE_TYPE;
  202.                   ITEM : in STRING;
  203.                   BRK  : in BREAK_TYPE := BREAK) is
  204.   begin
  205.     PRINT(CURRENT_OUTPUT,LINE,ITEM,BRK);
  206.   end PRINT;
  207.  
  208.   procedure PRINT(ITEM : in STRING; BRK : in BREAK_TYPE := BREAK) is
  209.   begin
  210.     PRINT(CURRENT_OUTPUT,DEFAULT_LINE,ITEM,BRK);
  211.   end PRINT;
  212.  
  213.   procedure PRINT_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE) is
  214.   begin
  215.     if LINE.INDEX /= LINE.INDENT + 1 then
  216.       PUT_LINE(FILE,LINE.DATA(1..LINE.INDEX-1));
  217.     end if;
  218.     for I in 1..LINE.INDENT loop
  219.       LINE.DATA(I) := ' ';
  220.     end loop;
  221.     LINE.INDEX := LINE.INDENT + 1;
  222.     LINE.BREAK := LINE.INDEX;
  223.   end PRINT_LINE;
  224.  
  225.   procedure PRINT_LINE(FILE : in FILE_TYPE) is
  226.   begin
  227.     PRINT_LINE(FILE,DEFAULT_LINE);
  228.   end PRINT_LINE;
  229.  
  230.   procedure PRINT_LINE(LINE : in LINE_TYPE) is
  231.   begin
  232.     PRINT_LINE(CURRENT_OUTPUT,LINE);
  233.   end PRINT_LINE;
  234.  
  235.   procedure PRINT_LINE is
  236.   begin
  237.     PRINT_LINE(CURRENT_OUTPUT,DEFAULT_LINE);
  238.   end PRINT_LINE;
  239.  
  240.   procedure BLANK_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE) is
  241.   begin
  242.     if LINE.USED_YET then
  243.       NEW_LINE(FILE);
  244.     end if;
  245.   end BLANK_LINE;
  246.  
  247.   procedure BLANK_LINE(FILE : in FILE_TYPE) is
  248.   begin
  249.     BLANK_LINE(FILE,DEFAULT_LINE);
  250.   end BLANK_LINE;
  251.  
  252.   procedure BLANK_LINE(LINE : in LINE_TYPE) is
  253.   begin
  254.     BLANK_LINE(CURRENT_OUTPUT,LINE);
  255.   end BLANK_LINE;
  256.  
  257.   procedure BLANK_LINE is
  258.   begin
  259.     BLANK_LINE(CURRENT_OUTPUT,DEFAULT_LINE);
  260.   end BLANK_LINE;
  261.  
  262.   package body INTEGER_PRINT is
  263.  
  264.     procedure PRINT(FILE : in FILE_TYPE;
  265.                     LINE : in LINE_TYPE;
  266.                     ITEM : in NUM;
  267.                     BRK  : in BREAK_TYPE := BREAK) is
  268.       S : STRING(1..NUM'WIDTH);
  269.       L : NATURAL;
  270.     begin
  271.       PRINT(S,L,ITEM);
  272.       PRINT(FILE,LINE,S(1..L),BRK);
  273.     end PRINT;
  274.  
  275.     procedure PRINT(FILE : in FILE_TYPE;
  276.                     ITEM : in NUM;
  277.                     BRK  : in BREAK_TYPE := BREAK) is
  278.     begin
  279.       PRINT(FILE,DEFAULT_LINE,ITEM,BRK);
  280.     end PRINT;
  281.  
  282.     procedure PRINT(LINE : in LINE_TYPE;
  283.                     ITEM : in NUM;
  284.                     BRK  : in BREAK_TYPE := BREAK) is
  285.     begin
  286.       PRINT(CURRENT_OUTPUT,LINE,ITEM,BRK);
  287.     end PRINT;
  288.  
  289.     procedure PRINT(ITEM : in NUM;
  290.                     BRK  : in BREAK_TYPE := BREAK) is
  291.     begin
  292.       PRINT(CURRENT_OUTPUT,DEFAULT_LINE,ITEM,BRK);
  293.     end PRINT;
  294.  
  295.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM) is
  296.       S : constant STRING := NUM'IMAGE(ITEM);
  297.       F : NATURAL := S'FIRST; -- Bug in DG Compiler -- S'FIRST /= 1 ! ! ! ! ! !
  298.       L : NATURAL;
  299.     begin
  300.       if S(F) = ' ' then
  301.         F := F + 1;
  302.       end if;
  303.       if TO'LENGTH < S'LAST - F + 1 then
  304.         raise LAYOUT_ERROR;
  305.       end if;
  306.       L := TO'FIRST + S'LAST - F;
  307.       TO(TO'FIRST..L) := S(F..S'LAST);
  308.       LAST := L;
  309.     end PRINT;
  310.  
  311.   end INTEGER_PRINT;
  312.  
  313.   package body FLOAT_PRINT is
  314.  
  315.     package NUM_IO is new FLOAT_IO(NUM);
  316.       use NUM_IO;
  317.  
  318.     procedure PRINT(FILE : in FILE_TYPE;
  319.                     LINE : in LINE_TYPE;
  320.                     ITEM : in NUM;
  321.                     BRK  : in BREAK_TYPE := BREAK) is
  322.       S : STRING(1..DEFAULT_FORE + DEFAULT_AFT + DEFAULT_EXP + 2);
  323.       L : NATURAL;
  324.     begin
  325.       PRINT(S,L,ITEM);
  326.       PRINT(FILE,LINE,S(1..L),BRK);
  327.     end PRINT;
  328.  
  329.     procedure PRINT(FILE : in FILE_TYPE;
  330.                     ITEM : in NUM;
  331.                     BRK  : in BREAK_TYPE := BREAK) is
  332.     begin
  333.       PRINT(FILE,DEFAULT_LINE,ITEM,BRK);
  334.     end PRINT;
  335.  
  336.     procedure PRINT(LINE : in LINE_TYPE;
  337.                     ITEM : in NUM;
  338.                     BRK  : in BREAK_TYPE := BREAK) is
  339.     begin
  340.       PRINT(CURRENT_OUTPUT,LINE,ITEM,BRK);
  341.     end PRINT;
  342.  
  343.     procedure PRINT(ITEM : in NUM;
  344.                     BRK  : in BREAK_TYPE := BREAK) is
  345.     begin
  346.       PRINT(CURRENT_OUTPUT,DEFAULT_LINE,ITEM,BRK);
  347.     end PRINT;
  348.  
  349.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM) is
  350.       S         : STRING(1..DEFAULT_FORE + DEFAULT_AFT + DEFAULT_EXP + 2);
  351.       EXP       : INTEGER;
  352.       E_INDEX   : NATURAL := S'LAST - DEFAULT_EXP;
  353.       DOT_INDEX : NATURAL := DEFAULT_FORE + 1;
  354.       L         : NATURAL := 0;
  355.     begin
  356.       PUT(S,ITEM);
  357.       EXP := INTEGER'VALUE(S(E_INDEX+1..S'LAST));
  358.       if EXP >= 0 and then EXP <= DEFAULT_AFT-1 then
  359.         S(DOT_INDEX..DOT_INDEX+EXP-1) := S(DOT_INDEX+1..DOT_INDEX+EXP);
  360.         S(DOT_INDEX+EXP) := '.';
  361.         for I in E_INDEX..S'LAST loop
  362.           S(I) := ' ';
  363.         end loop;
  364.       end if;
  365.       for I in reverse 1..E_INDEX-1 loop
  366.         exit when S(I) /= '0' or else S(I-1) = '.';
  367.         S(I) := ' ';
  368.       end loop;
  369.       for I in S'RANGE loop
  370.         if S(I) /= ' ' then
  371.           L := L + 1;
  372.           TO(L) := S(I);
  373.         end if;
  374.       end loop;
  375.       LAST := L;
  376.     exception
  377.       when CONSTRAINT_ERROR =>
  378.         raise LAYOUT_ERROR;
  379.     end PRINT;
  380.  
  381.   end FLOAT_PRINT;
  382.  
  383. end TEXT_PRINT;
  384. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  385. --txtinp.ada
  386. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  387. with TEXT_IO; 
  388.   use TEXT_IO;
  389.  
  390. package TEXT_INPUT is
  391.  
  392.   type STRING_LINK is access STRING;
  393.  
  394.   type BUFFER_TYPE is private;
  395.  
  396.   package INTEGER_IO is new TEXT_IO.INTEGER_IO(INTEGER);
  397.   package FLOAT_IO   is new TEXT_IO.FLOAT_IO(FLOAT);
  398.     use INTEGER_IO, FLOAT_IO;
  399.  
  400.   function MAKE_BUFFER(LENGTH : POSITIVE) return BUFFER_TYPE;
  401.  
  402.   procedure OPEN_INPUT(BUFFER : in out BUFFER_TYPE;
  403.                        MODE   : in FILE_MODE;
  404.                        NAME   : in STRING);
  405.  
  406.   procedure CLOSE_INPUT(BUFFER : in out BUFFER_TYPE);
  407.  
  408.   function END_OF_FILE(BUFFER : BUFFER_TYPE) return BOOLEAN;
  409.  
  410.   procedure CARD_ERROR(BUFFER : in BUFFER_TYPE; MESSAGE : in STRING);
  411.  
  412.   procedure IN_IDENT(BUFFER : in out BUFFER_TYPE; -- calls NEXT_TOKEN!
  413.                      IDENT  : out    STRING;      -- leaves ptr after ident
  414.                      LAST   : out    NATURAL);
  415.  
  416.   function IN_INTEGER(BUFFER : BUFFER_TYPE) return INTEGER;
  417.   function IN_FLOAT  (BUFFER : BUFFER_TYPE) return FLOAT;
  418.   function IN_STRING (BUFFER : BUFFER_TYPE) return STRING_LINK;
  419.  
  420. private
  421.  
  422.   type BUFFER_REC(LENGTH : POSITIVE) is
  423.     record
  424.       BUFFER : STRING(1..LENGTH);
  425.       FILE   : FILE_TYPE;
  426.       NEXT   : POSITIVE := 1;
  427.       LAST   : NATURAL  := 0;
  428.     end record;
  429.  
  430.   type BUFFER_TYPE is access BUFFER_REC;
  431.  
  432. end TEXT_INPUT;
  433.  
  434. with TEXT_IO;
  435.   use TEXT_IO;
  436.  
  437. package body TEXT_INPUT is
  438.  
  439.   function MAKE_BUFFER(LENGTH : POSITIVE) return BUFFER_TYPE is
  440.   begin
  441.     return new BUFFER_REC(LENGTH);
  442.   end MAKE_BUFFER;
  443.  
  444.   procedure OPEN_INPUT(BUFFER : in out BUFFER_TYPE;
  445.                        MODE   : in FILE_MODE;
  446.                        NAME   : in STRING) is
  447.   begin
  448.     OPEN(BUFFER.FILE,MODE,NAME);
  449.   end OPEN_INPUT;
  450.  
  451.   procedure CLOSE_INPUT(BUFFER : in out BUFFER_TYPE) is
  452.   begin
  453.     CLOSE(BUFFER.FILE);
  454.   end CLOSE_INPUT;
  455.  
  456.   function END_OF_FILE(BUFFER : BUFFER_TYPE) return BOOLEAN is
  457.   begin
  458.     return END_OF_FILE(BUFFER.FILE);
  459.   end END_OF_FILE;
  460.  
  461.   procedure CARD_ERROR(BUFFER : in BUFFER_TYPE; MESSAGE : in STRING) is
  462.   begin
  463.     PUT_LINE("***** Error on input card:");
  464.     PUT_LINE(BUFFER.BUFFER(1..BUFFER.LAST));
  465.     PUT_LINE(MESSAGE);
  466.     raise DATA_ERROR;
  467.   end CARD_ERROR;
  468.  
  469.   procedure NEXT_LINE(BUFFER : in BUFFER_TYPE) is
  470.   begin
  471.     loop
  472.       GET_LINE(BUFFER.FILE,BUFFER.BUFFER,BUFFER.LAST);
  473.       exit when BUFFER.LAST >= 2 and then BUFFER.BUFFER(1..2) /= "--";
  474.       exit when BUFFER.LAST = 1;
  475.     end loop;
  476.     BUFFER.NEXT := 1;
  477.   end NEXT_LINE;
  478.  
  479.   procedure NEXT_TOKEN(BUFFER : in BUFFER_TYPE) is
  480.   begin
  481.     loop
  482.       if BUFFER.NEXT > BUFFER.LAST then
  483.         NEXT_LINE(BUFFER);
  484.       end if;
  485.       if BUFFER.BUFFER(BUFFER.NEXT) = '-' and then
  486.           BUFFER.NEXT < BUFFER.LAST and then
  487.           BUFFER.BUFFER(BUFFER.NEXT+1) = '-' then
  488.         NEXT_LINE(BUFFER);
  489.       end if;
  490.       exit when BUFFER.BUFFER(BUFFER.NEXT) /= ' ' and then
  491.           BUFFER.BUFFER(BUFFER.NEXT) /= ASCII.HT;
  492.       BUFFER.NEXT := BUFFER.NEXT + 1;
  493.     end loop;
  494.   end NEXT_TOKEN;
  495.  
  496.   function TOKEN_END(BUFFER : BUFFER_TYPE) return POSITIVE is
  497.     PTR : POSITIVE;
  498.   begin
  499.     NEXT_TOKEN(BUFFER);
  500.     PTR := BUFFER.NEXT;
  501.     while PTR <= BUFFER.LAST and then BUFFER.BUFFER(PTR) /= ' ' and then
  502.         BUFFER.BUFFER(PTR) /= ASCII.HT loop
  503.       PTR := PTR + 1;
  504.     end loop;
  505.     return PTR-1;
  506.   end TOKEN_END;
  507.  
  508.   procedure IN_IDENT(BUFFER : in out BUFFER_TYPE;
  509.                      IDENT  : out    STRING;
  510.                      LAST   : out    NATURAL) is
  511.     TOKEND,
  512.     TLAST : POSITIVE;
  513.   begin
  514.     TOKEND := TOKEN_END(BUFFER);
  515.     TLAST := IDENT'FIRST + TOKEND - BUFFER.NEXT;
  516.     IDENT(IDENT'FIRST..TLAST) := BUFFER.BUFFER(BUFFER.NEXT..TOKEND);
  517.     LAST := TLAST;
  518.     BUFFER.NEXT := TOKEND + 1;
  519.   end IN_IDENT;
  520.  
  521.   function IN_INTEGER(BUFFER : BUFFER_TYPE) return INTEGER is
  522.     TOKEND : POSITIVE;
  523.     INT,
  524.     LAST   : INTEGER;
  525.   begin
  526.     TOKEND := TOKEN_END(BUFFER);
  527.     GET(BUFFER.BUFFER(BUFFER.NEXT..TOKEND),INT,LAST);
  528.     BUFFER.NEXT := TOKEND + 1;
  529.     return INT;
  530.   end IN_INTEGER;
  531.  
  532.   function IN_FLOAT  (BUFFER : BUFFER_TYPE) return FLOAT is
  533.     TOKEND : POSITIVE;
  534.     FLT    : FLOAT;
  535.     LAST   : INTEGER;
  536.   begin
  537.     TOKEND := TOKEN_END(BUFFER);
  538.     GET(BUFFER.BUFFER(BUFFER.NEXT..TOKEND),FLT,LAST);
  539.     BUFFER.NEXT := TOKEND + 1;
  540.     return FLT;
  541.   end IN_FLOAT;
  542.  
  543.   function IN_STRING (BUFFER : BUFFER_TYPE) return STRING_LINK is
  544.     PTR : POSITIVE;
  545.     STR : STRING_LINK;
  546.   begin
  547.     NEXT_TOKEN(BUFFER);
  548.     if BUFFER.BUFFER(BUFFER.NEXT) /= '"' then
  549.       raise DATA_ERROR;
  550.     end if;
  551.     PTR := BUFFER.NEXT + 1;
  552.     while PTR <= BUFFER.LAST and then BUFFER.BUFFER(PTR) /= '"' loop
  553.       PTR := PTR + 1;
  554.     end loop;
  555.     if PTR > BUFFER.LAST then
  556.       raise DATA_ERROR;
  557.     end if;
  558.     STR := new STRING(1..PTR-BUFFER.NEXT-1);
  559.     STR.all := BUFFER.BUFFER(BUFFER.NEXT+1..PTR-1);
  560.     BUFFER.NEXT := PTR + 1;
  561.     return STR;
  562.   end IN_STRING;
  563.  
  564. end TEXT_INPUT;
  565. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  566. --sqldef.ada
  567. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  568. with TEXT_INPUT;
  569.   use TEXT_INPUT;
  570.  
  571. package SQL_DEFINITIONS is
  572.  
  573.   type TABLE is private;
  574.   type FIELD is private;
  575.  
  576.   type TABLE_NAME is private;
  577.   type FIELD_NAME is private;
  578.  
  579.   subtype STRING_LINK is TEXT_INPUT.STRING_LINK;
  580.  
  581.   type OPERATOR_TYPE is (O_SELECT, O_INSERT, O_DELETE, O_UPDATE, O_LIKE,
  582.       O_SUM, O_AVG, O_MAX, O_MIN, O_COUNT, O_IN, O_EXISTS, O_DESC, O_AND,
  583.       O_OR, O_XOR, O_EQ, O_NE, O_LT, O_LE, O_GT, O_GE, O_PLUS, O_MINUS, O_CAT,
  584.       O_UNARY_PLUS, O_UNARY_MINUS, O_TIMES, O_DIV, O_MOD, O_REM, O_POWER,
  585.       O_ABS, O_NOT);
  586.  
  587.   STAR,
  588.   NULL_FIELD : constant FIELD;
  589.   NULL_TABLE : constant TABLE;
  590.  
  591.   function MAKE_TABLE_NAME(NAME : STRING) return TABLE_NAME;
  592.  
  593.   function MAKE_FIELD(RELATION : TABLE_NAME; TEMPLATE : FIELD) return FIELD;
  594.  
  595.   function MAKE_FIELD(NAME : STRING) return FIELD;
  596.  
  597.   function TABLEIFY(F : FIELD) return TABLE;
  598.  
  599.   function FIELDIFY(F : FIELD)     return FIELD;
  600.   function FIELDIFY(F : INTEGER)   return FIELD;
  601.   function FIELDIFY(F : FLOAT)     return FIELD;
  602.   function FIELDIFY(F : STRING)    return FIELD;
  603.  
  604.   function L_FIELDIFY(F : FIELD)     return FIELD renames FIELDIFY;
  605.   function L_FIELDIFY(F : INTEGER)   return FIELD renames FIELDIFY;
  606.   function L_FIELDIFY(F : FLOAT)     return FIELD renames FIELDIFY;
  607.   function L_FIELDIFY(F : STRING)    return FIELD renames FIELDIFY;
  608.  
  609.   function R_FIELDIFY(F : FIELD)     return FIELD renames FIELDIFY;
  610.   function R_FIELDIFY(F : INTEGER)   return FIELD renames FIELDIFY;
  611.   function R_FIELDIFY(F : FLOAT)     return FIELD renames FIELDIFY;
  612.   function R_FIELDIFY(F : STRING)    return FIELD renames FIELDIFY;
  613.  
  614.   generic
  615.     TABLE_FIELD : FIELD;
  616.   function GET_TABLE return TABLE;
  617.  
  618.   generic
  619.     FIELD_NAME : FIELD;
  620.   function GET_FIELD_NAME return FIELD;
  621.  
  622.   generic
  623.     type TABLE_TYPE is private;
  624.     DATA : TABLE_TYPE;
  625.   function GET_FIELDS return TABLE_TYPE;
  626.  
  627.   generic
  628.     TABLE_FIELD : FIELD;
  629.   function INSERT_FIELDS(F : in FIELD) return FIELD;
  630.  
  631.   generic
  632.     type VALUE_TYPE is private;
  633.     with function FIELDIFY(F : VALUE_TYPE) return FIELD is <>;
  634.   function VALUES_GEN(V : VALUE_TYPE) return FIELD;
  635.  
  636.   generic
  637.     OPCODE : OPERATOR_TYPE;
  638.     type L_TYPE is private;
  639.     with function L_FIELDIFY(F : L_TYPE) return FIELD is <>;
  640.   function UNARY_OPERATOR(L : L_TYPE) return FIELD;
  641.  
  642.   generic
  643.     OPCODE : OPERATOR_TYPE;
  644.     type L_TYPE is private;
  645.     type R_TYPE is private;
  646.     with function L_FIELDIFY(F : L_TYPE) return FIELD is <>;
  647.     with function R_FIELDIFY(F : R_TYPE) return FIELD is <>;
  648.   function BINARY_OPERATOR(L : L_TYPE; R : R_TYPE) return FIELD;
  649.  
  650.   function SELEC(WHAT   : FIELD := NULL_FIELD;
  651.                  FROM   : TABLE := NULL_TABLE;
  652.                  WHERE  : FIELD := NULL_FIELD;
  653.                  GROUP  : FIELD := NULL_FIELD;
  654.                  HAVING : FIELD := NULL_FIELD;
  655.                  ORDER  : FIELD := NULL_FIELD) return FIELD;
  656.  
  657.   function INSERT_INTO(WHAT   : FIELD;
  658.                        VALUES : FIELD) return FIELD;
  659.  
  660.   function INSERT_INTO(WHAT   : TABLE;
  661.                        VALUES : FIELD) return FIELD;
  662.  
  663.   function INSERT_UNTO(WHAT   : FIELD;
  664.                        VALUES : FIELD) return FIELD renames INSERT_INTO;
  665.  
  666.   function INSERT_UNTO(WHAT   : TABLE;
  667.                        VALUES : FIELD) return FIELD renames INSERT_INTO;
  668.  
  669.   generic
  670.     type WHAT_TYPE is private;
  671.     type VALUE_TYPE is private;
  672.     with function INSERT_UNTO(WHAT : WHAT_TYPE; VALUES: FIELD) return FIELD
  673.         is <>;
  674.     with function FIELDIFY(VALUE : VALUE_TYPE) return FIELD is <>;
  675.   function INSERT_GEN(WHAT : WHAT_TYPE; VALUES : VALUE_TYPE) return FIELD;
  676.  
  677.   function DELETE(FROM  : TABLE := NULL_TABLE;
  678.                   WHERE : FIELD := NULL_FIELD) return FIELD;
  679.  
  680.   function UPDATE(WHAT  : TABLE := NULL_TABLE;
  681.                   SET   : FIELD;
  682.                   WHERE : FIELD := NULL_FIELD) return FIELD;
  683.  
  684.   function "&"(L : TABLE; R : TABLE) return TABLE;
  685.  
  686.   package SQL_FUNCTIONS is
  687.  
  688.     type DATABASE_TYPE is private;
  689.     type VALUE_LINK    is private;
  690.     type RECORD_LINK   is private;
  691.  
  692.     type EXTENDED_FIELD_INDEX is new NATURAL;
  693.     subtype FIELD_INDEX is EXTENDED_FIELD_INDEX
  694.         range 1..EXTENDED_FIELD_INDEX'LAST;
  695.  
  696.     type EXTENDED_TABLE_INDEX is new NATURAL;
  697.     subtype TABLE_INDEX is EXTENDED_TABLE_INDEX
  698.         range 1..EXTENDED_TABLE_INDEX'LAST;
  699.  
  700.     package PROGRAM_FUNCTIONS is
  701.  
  702.       type CURSOR_TYPE is private;
  703.  
  704.       function  EXECUTE     (F : in FIELD) return CURSOR_TYPE;
  705.       procedure EXECUTE     (F : in FIELD);
  706.       procedure LIST        (F : in FIELD);
  707.       procedure SET_DATABASE(DB : in DATABASE_TYPE);
  708.       procedure NEXT_RECORD (CURSOR : in out CURSOR_TYPE);
  709.  
  710.       procedure FETCH(CURSOR : in  CURSOR_TYPE;
  711.                       FIELD  : in  FIELD_INDEX;
  712.                       INT    : out INTEGER);
  713.  
  714.       procedure FETCH(CURSOR : in  CURSOR_TYPE;
  715.                       FIELD  : in  FIELD_INDEX;
  716.                       FLT    : out FLOAT);
  717.  
  718.       procedure FETCH(CURSOR : in  CURSOR_TYPE;
  719.                       FIELD  : in  FIELD_INDEX;
  720.                       STR    : out STRING;
  721.                       LAST   : out NATURAL);
  722.  
  723.       function FETCH(CURSOR : CURSOR_TYPE;
  724.                      FIELD  : FIELD_INDEX) return INTEGER;
  725.  
  726.       function FETCH(CURSOR : CURSOR_TYPE;
  727.                      FIELD  : FIELD_INDEX) return FLOAT;
  728.  
  729.       function FETCH(CURSOR : CURSOR_TYPE;
  730.                      FIELD  : FIELD_INDEX) return STRING;
  731.  
  732.       CALL_ERROR          : exception;
  733.       DONE_ERROR          : exception;
  734.       FIELD_ERROR         : exception;
  735.       SYNTAX_ERROR        : exception;
  736.       TABLE_ERROR         : exception;
  737.       TRUNCATE_ERROR      : exception;
  738.       TYPE_ERROR          : exception;
  739.       UNIMPLEMENTED_ERROR : exception;
  740.  
  741.     private
  742.  
  743.       type QUERY_NODE_REC;
  744.  
  745.       type QUERY_NODE is access QUERY_NODE_REC;
  746.  
  747.       type QUERY_NODE_REC is
  748.         record
  749.           NEXT_NODE : QUERY_NODE;
  750.           FIELD     : FIELD_INDEX;
  751.           VALUE     : VALUE_LINK;
  752.         end record;
  753.  
  754.       type CURSOR_TYPE is
  755.         record
  756.           QUERY          : QUERY_NODE;
  757.           CURRENT_RECORD : RECORD_LINK;
  758.           NEW_QUERY      : BOOLEAN := TRUE;
  759.         end record;
  760.  
  761.     end PROGRAM_FUNCTIONS;
  762.  
  763.     package SHOW_PACKAGE is
  764.       procedure SHOW (F : in FIELD);
  765.     end SHOW_PACKAGE;
  766.  
  767.     package BULK_FUNCTIONS is
  768.       function  LOAD_DATABASE(FILE_NAME : in STRING) return DATABASE_TYPE;
  769.       procedure SAVE_DATABASE(FILE_NAME : in STRING;
  770.                               DATABASE  : in DATABASE_TYPE);
  771.     end BULK_FUNCTIONS;
  772.  
  773.     subtype CURSOR_TYPE is PROGRAM_FUNCTIONS.CURSOR_TYPE;
  774.  
  775.     function EXECUTE(F : FIELD) return CURSOR_TYPE
  776.         renames PROGRAM_FUNCTIONS.EXECUTE;
  777.  
  778.     procedure EXECUTE(F : in FIELD) renames PROGRAM_FUNCTIONS.EXECUTE;
  779.     procedure LIST   (F : in FIELD) renames PROGRAM_FUNCTIONS.LIST;
  780.     procedure SHOW   (F : in FIELD) renames SHOW_PACKAGE.SHOW;
  781.  
  782.     procedure SET_DATABASE(DB : in DATABASE_TYPE)
  783.         renames PROGRAM_FUNCTIONS.SET_DATABASE;
  784.  
  785.     procedure NEXT_RECORD(CURSOR : in out CURSOR_TYPE)
  786.         renames PROGRAM_FUNCTIONS.NEXT_RECORD;
  787.  
  788.     procedure FETCH(CURSOR : in  CURSOR_TYPE;
  789.                     FIELD  : in  FIELD_INDEX;
  790.                     INT    : out INTEGER) renames PROGRAM_FUNCTIONS.FETCH;
  791.  
  792.     procedure FETCH(CURSOR : in  CURSOR_TYPE;
  793.                     FIELD  : in  FIELD_INDEX;
  794.                     FLT    : out FLOAT) renames PROGRAM_FUNCTIONS.FETCH;
  795.  
  796.     procedure FETCH(CURSOR : in  CURSOR_TYPE;
  797.                     FIELD  : in  FIELD_INDEX;
  798.                     STR    : out STRING;
  799.                     LAST   : out NATURAL) renames PROGRAM_FUNCTIONS.FETCH;
  800.  
  801.     function FETCH(CURSOR : CURSOR_TYPE;
  802. mes PROGRAM_FUNCTIONS.FETCH;
  803.  
  804.     function FETCH(CURSOR : CURSOR_TYPE;
  805.                    FIELD  : FIELD_INDEX) return FLOAT
  806.         renames PROGRAM_FUNCTIONS.FETCH;
  807.  
  808.     function FETCH(CURSOR : CURSOR_TYPE;
  809.                    FIELD  : FIELD_INDEX) return STRING
  810.         renames PROGRAM_FUNCTIONS.FETCH;
  811.  
  812.     function LOAD_DATABASE(FILE_NAME : in STRING) return DATABASE_TYPE renames
  813.       BULK_FUNCTIONS.LOAD_DATABASE;
  814.  
  815.     procedure SAVE_DATABASE(FILE_NAME : in STRING;
  816.                             DATABASE  : in DATABASE_TYPE) renames
  817.       BULK_FUNCTIONS.SAVE_DATABASE;
  818.  
  819.     CALL_ERROR          : exception renames PROGRAM_FUNCTIONS.CALL_ERROR;
  820.     DONE_ERROR          : exception renames PROGRAM_FUNCTIONS.DONE_ERROR;
  821.     FIELD_ERROR         : exception renames PROGRAM_FUNCTIONS.FIELD_ERROR;
  822.     SYNTAX_ERROR        : exception renames PROGRAM_FUNCTIONS.SYNTAX_ERROR;
  823.     TABLE_ERROR         : exception renames PROGRAM_FUNCTIONS.TABLE_ERROR;
  824.     TRUNCATE_ERROR      : exception renames PROGRAM_FUNCTIONS.TRUNCATE_ERROR;
  825.     TYPE_ERROR          : exception renames PROGRAM_FUNCTIONS.TYPE_ERROR;
  826.     UNIMPLEMENTED_ERROR : exception renames
  827.         PROGRAM_FUNCTIONS.UNIMPLEMENTED_ERROR;
  828.  
  829.   private
  830.  
  831.     type DATABASE_FIELD_TYPE is (INTEGER_FIELD, FLOAT_FIELD, STRING_FIELD);
  832.  
  833.     type VALUE_TYPE(FIELD_TYPE : DATABASE_FIELD_TYPE) is
  834.       record
  835.         case FIELD_TYPE is
  836.           when INTEGER_FIELD =>
  837.             INTEGER_VALUE : INTEGER;
  838.           when FLOAT_FIELD =>
  839.             FLOAT_VALUE   : FLOAT;
  840.           when STRING_FIELD =>
  841.             STRING_VALUE  : STRING_LINK;
  842.         end case;
  843.       end record;
  844.  
  845.     type VALUE_LINK is access VALUE_TYPE;
  846.  
  847.     type VALUE_ARRAY is array(FIELD_INDEX range <>) of VALUE_LINK;
  848.  
  849.     type RECORD_TYPE(NUMBER_FIELDS : EXTENDED_FIELD_INDEX);
  850.  
  851.     type RECORD_LINK is access RECORD_TYPE;
  852.  
  853.     type RECORD_TYPE(NUMBER_FIELDS : EXTENDED_FIELD_INDEX) is
  854.       record
  855.         NEXT_RECORD : RECORD_LINK;
  856.         VALUES      : VALUE_ARRAY(1..NUMBER_FIELDS);
  857.       end record;
  858.  
  859.     type FIELD_TYPE is
  860.       record
  861.         NAME      : FIELD_NAME;
  862.         DATA_TYPE : DATABASE_FIELD_TYPE;
  863.         SIZE      : POSITIVE;
  864.       end record;
  865.  
  866.     type FIELD_ARRAY is array(FIELD_INDEX range <>) of FIELD_TYPE;
  867.  
  868.     type TABLE_TYPE(NUMBER_FIELDS : EXTENDED_FIELD_INDEX) is
  869.       record
  870.         NAME    : TABLE_NAME;
  871.         RECORDS : RECORD_LINK;
  872.         FIELDS  : FIELD_ARRAY(1..NUMBER_FIELDS);
  873.       end record;
  874.  
  875.     type TABLE_LINK is access TABLE_TYPE;
  876.  
  877.     type TABLE_ARRAY is array(TABLE_INDEX range <>) of TABLE_LINK;
  878.  
  879.     type DATABASE_TYPE is access TABLE_ARRAY;
  880.  
  881.   end SQL_FUNCTIONS;
  882.  
  883.   subtype DATABASE_TYPE is SQL_FUNCTIONS.DATABASE_TYPE;
  884.   subtype CURSOR_TYPE   is SQL_FUNCTIONS.CURSOR_TYPE;
  885.   subtype FIELD_INDEX   is SQL_FUNCTIONS.FIELD_INDEX;
  886.  
  887.   function EXECUTE(F : FIELD) return CURSOR_TYPE
  888.       renames SQL_FUNCTIONS.EXECUTE;
  889.  
  890.   procedure EXECUTE(F : in FIELD) renames SQL_FUNCTIONS.EXECUTE;
  891.   procedure LIST   (F : in FIELD) renames SQL_FUNCTIONS.LIST;
  892.   procedure SHOW   (F : in FIELD) renames SQL_FUNCTIONS.SHOW;
  893.  
  894.   procedure SET_DATABASE(DB : in DATABASE_TYPE)
  895.       renames SQL_FUNCTIONS.SET_DATABASE;
  896.  
  897.   procedure NEXT_RECORD(CURSOR : in out CURSOR_TYPE)
  898.       renames SQL_FUNCTIONS.NEXT_RECORD;
  899.  
  900.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  901.                   FIELD  : in  FIELD_INDEX;
  902.                   INT    : out INTEGER) renames SQL_FUNCTIONS.FETCH;
  903.  
  904.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  905.                   FIELD  : in  FIELD_INDEX;
  906.                   FLT    : out FLOAT) renames SQL_FUNCTIONS.FETCH;
  907.  
  908.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  909.                   FIELD  : in  FIELD_INDEX;
  910.                   STR    : out STRING;
  911.                   LAST   : out NATURAL) renames SQL_FUNCTIONS.FETCH;
  912.  
  913.   function FETCH(CURSOR : CURSOR_TYPE;
  914.                  FIELD  : FIELD_INDEX) return INTEGER
  915.       renames SQL_FUNCTIONS.FETCH;
  916.  
  917.   function FETCH(CURSOR : CURSOR_TYPE;
  918.                  FIELD  : FIELD_INDEX) return FLOAT
  919.       renames SQL_FUNCTIONS.FETCH;
  920.  
  921.   function FETCH(CURSOR : CURSOR_TYPE;
  922.                  FIELD  : FIELD_INDEX) return STRING
  923.       renames SQL_FUNCTIONS.FETCH;
  924.  
  925.   function  LOAD_DATABASE(FILE_NAME : in STRING) return DATABASE_TYPE renames
  926.       SQL_FUNCTIONS.LOAD_DATABASE;
  927.  
  928.   procedure SAVE_DATABASE(FILE_NAME : in STRING;
  929.                           DATABASE  : in DATABASE_TYPE) renames
  930.       SQL_FUNCTIONS.SAVE_DATABASE;
  931.  
  932.   CALL_ERROR          : exception renames SQL_FUNCTIONS.CALL_ERROR;
  933.   DONE_ERROR          : exception renames SQL_FUNCTIONS.DONE_ERROR;
  934.   FIELD_ERROR         : exception renames SQL_FUNCTIONS.FIELD_ERROR;
  935.   SYNTAX_ERROR        : exception renames SQL_FUNCTIONS.SYNTAX_ERROR;
  936.   TABLE_ERROR         : exception renames SQL_FUNCTIONS.TABLE_ERROR;
  937.   TRUNCATE_ERROR      : exception renames SQL_FUNCTIONS.TRUNCATE_ERROR;
  938.   TYPE_ERROR          : exception renames SQL_FUNCTIONS.TYPE_ERROR;
  939.   UNIMPLEMENTED_ERROR : exception renames SQL_FUNCTIONS.UNIMPLEMENTED_ERROR;
  940.  
  941. private
  942.  
  943.   type TABLE_NAME_STRING is new STRING;
  944.   type FIELD_NAME_STRING is new STRING;
  945.  
  946.   type TABLE_NAME is access TABLE_NAME_STRING;
  947.   type FIELD_NAME is access FIELD_NAME_STRING;
  948.  
  949.   type TABLE_REC;
  950.  
  951.   type TABLE is access TABLE_REC;
  952.  
  953.   type TABLE_REC is
  954.     record
  955.       NAME      : TABLE_NAME;
  956.       NEXT_LINK : TABLE;
  957.     end record;
  958.  
  959.   type FIELD_TYPE_TYPE is (OPERATOR, INTEGER_LITERAL, STRING_LITERAL,
  960.     FLOAT_LITERAL, EMPTY, QUALIFIED_FIELD, UNQUALIFIED_FIELD, FROM_LIST);
  961.  
  962.   type FIELD_REC(FIELD_TYPE : FIELD_TYPE_TYPE);
  963.  
  964.   type FIELD is access FIELD_REC;
  965.  
  966.   type FIELD_REC(FIELD_TYPE : FIELD_TYPE_TYPE) is
  967.     record
  968.       ACROSS_LINK : FIELD;
  969.       case FIELD_TYPE is
  970.         when FROM_LIST =>
  971.           TABLE_LINK    : TABLE;
  972.         when OPERATOR =>
  973.           OPCODE        : OPERATOR_TYPE;
  974.           DOWN_LINK     : FIELD;
  975.         when INTEGER_LITERAL =>
  976.           INTEGER_VALUE : INTEGER;
  977.         when STRING_LITERAL =>
  978.           STRING_VALUE  : STRING_LINK;
  979.         when FLOAT_LITERAL =>
  980.           FLOAT_VALUE   : FLOAT;
  981.         when EMPTY =>
  982.           null;
  983.         when QUALIFIED_FIELD | UNQUALIFIED_FIELD =>
  984.           RELATION      : TABLE_NAME; -- null for UNQUALIFIED_FIELD
  985.           NAME          : FIELD_NAME;
  986.       end case;
  987.     end record;
  988.  
  989.   STAR : constant FIELD := new FIELD_REC'(
  990.     UNQUALIFIED_FIELD,null,null,new FIELD_NAME_STRING'("*"));
  991.  
  992.   NULL_TABLE : constant TABLE := null;
  993.   NULL_FIELD : constant FIELD := null;
  994.  
  995. end SQL_DEFINITIONS;
  996.  
  997. package body SQL_DEFINITIONS is
  998.  
  999.   function MAKE_TABLE_NAME(NAME : STRING) return TABLE_NAME is
  1000.   begin
  1001.     return new TABLE_NAME_STRING'(TABLE_NAME_STRING(NAME));
  1002.   end;
  1003.  
  1004.   function MAKE_FIELD(RELATION : TABLE_NAME; TEMPLATE : FIELD) return FIELD is
  1005.   begin
  1006.     return new FIELD_REC'(QUALIFIED_FIELD,null,RELATION,TEMPLATE.NAME);
  1007.   end MAKE_FIELD;
  1008.  
  1009.   function MAKE_FIELD(NAME : STRING) return FIELD is
  1010.   begin
  1011.     return new FIELD_REC'(
  1012.       UNQUALIFIED_FIELD,null,null,
  1013.         new FIELD_NAME_STRING'(FIELD_NAME_STRING(NAME)) );
  1014.   end MAKE_FIELD;
  1015.  
  1016.   function TABLEIFY(F : FIELD) return TABLE is
  1017.   begin
  1018.     return new TABLE_REC'(F.RELATION,null);
  1019.   end TABLEIFY;
  1020.  
  1021.   function GET_TABLE return TABLE is
  1022.   begin
  1023.     return TABLEIFY(TABLE_FIELD);
  1024.   end GET_TABLE;
  1025.  
  1026.   function GET_FIELD_NAME return FIELD is
  1027.   begin
  1028.     return FIELD_NAME;
  1029.   end GET_FIELD_NAME;
  1030.  
  1031.   function GET_FIELDS return TABLE_TYPE is
  1032.   begin
  1033.     return DATA;
  1034.   end GET_FIELDS;
  1035.  
  1036.   function INSERT_FIELDS(F : in FIELD) return FIELD is
  1037.   begin
  1038.     return new FIELD_REC'(FROM_LIST,F,TABLEIFY(TABLE_FIELD));
  1039.   end INSERT_FIELDS;
  1040.  
  1041.   function FIELDIFY(F : FIELD) return FIELD is
  1042.   begin
  1043.     if F = null then
  1044.       return new FIELD_REC'(EMPTY,null);
  1045.     else
  1046.       case F.FIELD_TYPE is
  1047.         when QUALIFIED_FIELD | UNQUALIFIED_FIELD =>
  1048.           return new FIELD_REC'(F.all);
  1049.         when others =>
  1050.           return F;
  1051.       end case;
  1052.     end if;
  1053.   end FIELDIFY;
  1054.  
  1055.   function FIELDIFY(F : INTEGER) return FIELD is
  1056.   begin
  1057.     return new FIELD_REC'(INTEGER_LITERAL,null,F);
  1058.   end FIELDIFY;
  1059.  
  1060.   function FIELDIFY(F : FLOAT) return FIELD is
  1061.   begin
  1062.     return new FIELD_REC'(FLOAT_LITERAL,null,F);
  1063.   end FIELDIFY;
  1064.  
  1065.   function FIELDIFY(F : STRING) return FIELD is
  1066.   begin
  1067.     return new FIELD_REC'(STRING_LITERAL,null,new STRING'(F));
  1068.   end FIELDIFY;
  1069.  
  1070.   function VALUES_GEN(V : VALUE_TYPE) return FIELD is
  1071.   begin
  1072.     return FIELDIFY(V);
  1073.   end VALUES_GEN;
  1074.  
  1075.   function UNARY_OPERATOR(L : L_TYPE) return FIELD is
  1076.   begin
  1077.     return new FIELD_REC'(OPERATOR,null,OPCODE,L_FIELDIFY(L) );
  1078.   end UNARY_OPERATOR;
  1079.  
  1080.   function BINARY_OPERATOR(L : L_TYPE; R : R_TYPE) return FIELD is
  1081.     LF : FIELD;
  1082.   begin
  1083.     LF := L_FIELDIFY(L);
  1084.     LF.ACROSS_LINK := R_FIELDIFY(R);
  1085.     return new FIELD_REC'(OPERATOR,null,OPCODE,LF);
  1086.   end BINARY_OPERATOR;
  1087.  
  1088.   function SELEC(WHAT   : FIELD := NULL_FIELD;
  1089.                  FROM   : TABLE := NULL_TABLE;
  1090.                  WHERE  : FIELD := NULL_FIELD;
  1091.                  GROUP  : FIELD := NULL_FIELD;
  1092.                  HAVING : FIELD := NULL_FIELD;
  1093.                  ORDER  : FIELD := NULL_FIELD) return FIELD is
  1094.     RET_VALUE,F : FIELD;
  1095.   begin
  1096.     F := FIELDIFY(WHAT);
  1097.     RET_VALUE := new FIELD_REC'(OPERATOR,null,O_SELECT,F);
  1098.     F.ACROSS_LINK := new FIELD_REC'(FROM_LIST,null,FROM); F := F.ACROSS_LINK;
  1099.     F.ACROSS_LINK := FIELDIFY(WHERE); F := F.ACROSS_LINK;
  1100.     F.ACROSS_LINK := FIELDIFY(GROUP); F := F.ACROSS_LINK;
  1101.     F.ACROSS_LINK := FIELDIFY(HAVING); F := F.ACROSS_LINK;
  1102.     F.ACROSS_LINK := FIELDIFY(ORDER); F := F.ACROSS_LINK;
  1103.     return RET_VALUE;
  1104.   end SELEC;
  1105.  
  1106.   function INSERT_INTO(WHAT   : FIELD;
  1107.                        VALUES : FIELD) return FIELD is
  1108.   begin
  1109.     return new FIELD_REC'(OPERATOR,FIELDIFY(WHAT),O_INSERT,FIELDIFY(VALUES));
  1110.   end INSERT_INTO;
  1111.  
  1112.   function INSERT_INTO(WHAT   : TABLE;
  1113.                        VALUES : FIELD) return FIELD is
  1114.   begin
  1115.     return new FIELD_REC'(OPERATOR,new FIELD_REC'(FROM_LIST,null,WHAT),
  1116.         O_INSERT,FIELDIFY(VALUES));
  1117.   end INSERT_INTO;
  1118.  
  1119.   function INSERT_GEN(WHAT : WHAT_TYPE; VALUES : VALUE_TYPE) return FIELD is
  1120.   begin
  1121.     return INSERT_UNTO(WHAT,FIELDIFY(VALUES));
  1122.   end INSERT_GEN;
  1123.  
  1124.   function DELETE(FROM  : TABLE := NULL_TABLE;
  1125.                   WHERE : FIELD := NULL_FIELD) return FIELD is
  1126.   begin
  1127.     return new FIELD_REC'(OPERATOR,null,O_DELETE,
  1128.         new FIELD_REC'(FROM_LIST,FIELDIFY(WHERE),FROM));
  1129.   end DELETE;
  1130.  
  1131.   function UPDATE(WHAT  : TABLE := NULL_TABLE;
  1132.                   SET   : FIELD;
  1133.                   WHERE : FIELD := NULL_FIELD) return FIELD is
  1134.     RET_VALUE, F : FIELD;
  1135.   begin
  1136.     F := new FIELD_REC'(FROM_LIST,null,WHAT);
  1137.     RET_VALUE := new FIELD_REC'(OPERATOR,null,O_UPDATE,F);
  1138.     F.ACROSS_LINK := FIELDIFY(SET); F := F.ACROSS_LINK;
  1139.     F.ACROSS_LINK := FIELDIFY(WHERE);
  1140.     return RET_VALUE;
  1141.   end UPDATE;
  1142.  
  1143.   function "&"(L : TABLE; R : TABLE) return TABLE is
  1144.     LP : TABLE := L;
  1145.   begin
  1146.     while LP.NEXT_LINK /= null loop
  1147.       LP := LP.NEXT_LINK;
  1148.     end loop;
  1149.     LP.NEXT_LINK := R;
  1150.     return L;
  1151.   end "&";
  1152.  
  1153.   package body SQL_FUNCTIONS is separate;
  1154.  
  1155. end SQL_DEFINITIONS;
  1156.  
  1157. with TEXT_PRINT;
  1158.   use TEXT_PRINT;
  1159.  
  1160. separate(SQL_DEFINITIONS)
  1161. package body SQL_FUNCTIONS is
  1162.  
  1163.   package INT_PRINT is new INTEGER_PRINT(INTEGER);
  1164.   package FLT_PRINT is new FLOAT_PRINT(FLOAT);
  1165.     use INT_PRINT, FLT_PRINT;
  1166.  
  1167.   package body PROGRAM_FUNCTIONS is separate;
  1168.   package body SHOW_PACKAGE is separate;
  1169.   package body BULK_FUNCTIONS is separate;
  1170.  
  1171. end SQL_FUNCTIONS;
  1172. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1173. --sqlops.ada
  1174. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1175. with SQL_DEFINITIONS;
  1176.   use SQL_DEFINITIONS;
  1177.  
  1178. package SQL_OPERATIONS is
  1179.  
  1180.   subtype TABLE is SQL_DEFINITIONS.TABLE;
  1181.   subtype FIELD is SQL_DEFINITIONS.FIELD;
  1182.  
  1183.   type STAR_TYPE is ('*');
  1184.  
  1185.   function SELEC(WHAT   : FIELD := NULL_FIELD;
  1186.                  FROM   : TABLE := NULL_TABLE;
  1187.                  WHERE  : FIELD := NULL_FIELD;
  1188.                  GROUP  : FIELD := NULL_FIELD;
  1189.                  HAVING : FIELD := NULL_FIELD;
  1190.                  ORDER  : FIELD := NULL_FIELD) return FIELD
  1191.     renames SQL_DEFINITIONS.SELEC;
  1192.  
  1193.   function SELEC(WHAT   : STAR_TYPE;
  1194.                  FROM   : TABLE := NULL_TABLE;
  1195.                  WHERE  : FIELD := NULL_FIELD;
  1196.                  GROUP  : FIELD := NULL_FIELD;
  1197.                  HAVING : FIELD := NULL_FIELD;
  1198.                  ORDER  : FIELD := NULL_FIELD) return FIELD;
  1199.  
  1200.   function INSERT_INTO(WHAT   : FIELD;
  1201.                        VALUES : FIELD) return FIELD
  1202.     renames SQL_DEFINITIONS.INSERT_INTO;
  1203.  
  1204.   function INSERT_INTO(WHAT   : TABLE;
  1205.                        VALUES : FIELD) return FIELD
  1206.     renames SQL_DEFINITIONS.INSERT_INTO;
  1207.  
  1208.   function INSERT_INTO is new INSERT_GEN(FIELD,INTEGER);
  1209.   function INSERT_INTO is new INSERT_GEN(FIELD,FLOAT);
  1210.   function INSERT_INTO is new INSERT_GEN(FIELD,STRING);
  1211.   function INSERT_INTO is new INSERT_GEN(TABLE,INTEGER);
  1212.   function INSERT_INTO is new INSERT_GEN(TABLE,FLOAT);
  1213.   function INSERT_INTO is new INSERT_GEN(TABLE,STRING);
  1214.  
  1215.   function DELETE(FROM  : TABLE := NULL_TABLE;
  1216.                   WHERE : FIELD := NULL_FIELD) return FIELD
  1217.     renames SQL_DEFINITIONS.DELETE;
  1218.  
  1219.   function UPDATE(WHAT  : TABLE := NULL_TABLE;
  1220.                   SET   : FIELD;
  1221.                   WHERE : FIELD := NULL_FIELD) return FIELD
  1222.     renames SQL_DEFINITIONS.UPDATE;
  1223.  
  1224.   function VALUES is new VALUES_GEN(FIELD);
  1225.   function VALUES is new VALUES_GEN(INTEGER);
  1226.   function VALUES is new VALUES_GEN(FLOAT);
  1227.   function VALUES is new VALUES_GEN(STRING);
  1228.  
  1229.   function LIKE is new BINARY_OPERATOR(O_LIKE,FIELD, FIELD);
  1230.   function LIKE is new BINARY_OPERATOR(O_LIKE,FIELD, STRING);
  1231.   function LIKE is new BINARY_OPERATOR(O_LIKE,STRING,FIELD);
  1232.  
  1233.   function SUM is new UNARY_OPERATOR(O_SUM,FIELD);
  1234.   function AVG is new UNARY_OPERATOR(O_AVG,FIELD);
  1235.   function MAX is new UNARY_OPERATOR(O_MAX,FIELD);
  1236.   function MIN is new UNARY_OPERATOR(O_MIN,FIELD);
  1237.  
  1238.   function COUNT is new UNARY_OPERATOR(O_COUNT,FIELD);
  1239.   function COUNT(X : STAR_TYPE) return FIELD;
  1240.  
  1241.   function IS_IN is new BINARY_OPERATOR(O_IN,FIELD,  FIELD);
  1242.   function IS_IN is new BINARY_OPERATOR(O_IN,INTEGER,FIELD);
  1243.   function IS_IN is new BINARY_OPERATOR(O_IN,FLOAT,  FIELD);
  1244.   function IS_IN is new BINARY_OPERATOR(O_IN,STRING, FIELD);
  1245.  
  1246.   function EXISTS is new UNARY_OPERATOR(O_EXISTS,FIELD);
  1247.  
  1248.   function DESC is new UNARY_OPERATOR(O_DESC,FIELD);
  1249.  
  1250.   function "and" is new BINARY_OPERATOR(O_AND,FIELD,FIELD);
  1251.  
  1252.   function "and" is new BINARY_OPERATOR(O_AND,INTEGER,INTEGER);
  1253.   function "and" is new BINARY_OPERATOR(O_AND,FLOAT,  FLOAT);
  1254.   function "and" is new BINARY_OPERATOR(O_AND,STRING, STRING);
  1255.   function "and" is new BINARY_OPERATOR(O_AND,INTEGER,FLOAT);
  1256.   function "and" is new BINARY_OPERATOR(O_AND,INTEGER,STRING);
  1257.   function "and" is new BINARY_OPERATOR(O_AND,FLOAT,  INTEGER);
  1258.   function "and" is new BINARY_OPERATOR(O_AND,FLOAT,  STRING);
  1259.   function "and" is new BINARY_OPERATOR(O_AND,STRING, INTEGER);
  1260.   function "and" is new BINARY_OPERATOR(O_AND,STRING, FLOAT);
  1261.   function "and" is new BINARY_OPERATOR(O_AND,INTEGER,FIELD);
  1262.   function "and" is new BINARY_OPERATOR(O_AND,FLOAT,  FIELD);
  1263.   function "and" is new BINARY_OPERATOR(O_AND,STRING, FIELD);
  1264.   function "and" is new BINARY_OPERATOR(O_AND,FIELD,  INTEGER);
  1265.   function "and" is new BINARY_OPERATOR(O_AND,FIELD,  FLOAT);
  1266.   function "and" is new BINARY_OPERATOR(O_AND,FIELD,  STRING);
  1267.  
  1268.   function "xor" is new BINARY_OPERATOR(O_XOR,FIELD,FIELD);
  1269.  
  1270.   function "or" is new BINARY_OPERATOR(O_OR,FIELD,FIELD);
  1271.  
  1272.   function "or" is new BINARY_OPERATOR(O_OR,INTEGER,INTEGER);
  1273.   function "or" is new BINARY_OPERATOR(O_OR,FLOAT,  FLOAT);
  1274.   function "or" is new BINARY_OPERATOR(O_OR,STRING, STRING);
  1275.   function "or" is new BINARY_OPERATOR(O_OR,INTEGER,FLOAT);
  1276.   function "or" is new BINARY_OPERATOR(O_OR,FLOAT,  INTEGER);
  1277.   function "or" is new BINARY_OPERATOR(O_OR,FIELD,  INTEGER);
  1278.   function "or" is new BINARY_OPERATOR(O_OR,FIELD,  FLOAT);
  1279.   function "or" is new BINARY_OPERATOR(O_OR,FIELD,  STRING);
  1280.   function "or" is new BINARY_OPERATOR(O_OR,INTEGER,FIELD);
  1281.   function "or" is new BINARY_OPERATOR(O_OR,FLOAT,  FIELD);
  1282.   function "or" is new BINARY_OPERATOR(O_OR,STRING, FIELD);
  1283.  
  1284.   function EQ is new BINARY_OPERATOR(O_EQ,FIELD,  FIELD);
  1285.   function EQ is new BINARY_OPERATOR(O_EQ,INTEGER,INTEGER);
  1286.   function EQ is new BINARY_OPERATOR(O_EQ,FLOAT  ,FLOAT);
  1287.   function EQ is new BINARY_OPERATOR(O_EQ,STRING, STRING);
  1288.   function EQ is new BINARY_OPERATOR(O_EQ,INTEGER,FLOAT);
  1289.   function EQ is new BINARY_OPERATOR(O_EQ,FLOAT,  INTEGER);
  1290.   function EQ is new BINARY_OPERATOR(O_EQ,FIELD,  INTEGER);
  1291.   function EQ is new BINARY_OPERATOR(O_EQ,FIELD,  FLOAT);
  1292.   function EQ is new BINARY_OPERATOR(O_EQ,FIELD,  STRING);
  1293.   function EQ is new BINARY_OPERATOR(O_EQ,INTEGER,FIELD);
  1294.   function EQ is new BINARY_OPERATOR(O_EQ,FLOAT,  FIELD);
  1295.   function EQ is new BINARY_OPERATOR(O_EQ,STRING, FIELD);
  1296.  
  1297.   function NE is new BINARY_OPERATOR(O_NE,FIELD,  FIELD);
  1298.   function NE is new BINARY_OPERATOR(O_NE,INTEGER,INTEGER);
  1299.   function NE is new BINARY_OPERATOR(O_NE,FLOAT,  FLOAT);
  1300.   function NE is new BINARY_OPERATOR(O_NE,STRING, STRING);
  1301.   function NE is new BINARY_OPERATOR(O_NE,INTEGER,FLOAT);
  1302.   function NE is new BINARY_OPERATOR(O_NE,FLOAT,  INTEGER);
  1303.   function NE is new BINARY_OPERATOR(O_NE,FIELD,  INTEGER);
  1304.   function NE is new BINARY_OPERATOR(O_NE,FIELD,  FLOAT);
  1305.   function NE is new BINARY_OPERATOR(O_NE,FIELD,  STRING);
  1306.   function NE is new BINARY_OPERATOR(O_NE,INTEGER,FIELD);
  1307.   function NE is new BINARY_OPERATOR(O_NE,FLOAT,  FIELD);
  1308.   function NE is new BINARY_OPERATOR(O_NE,STRING, FIELD);
  1309.  
  1310.   function "<" is new BINARY_OPERATOR(O_LT,FIELD,  FIELD);
  1311.   function "<" is new BINARY_OPERATOR(O_LT,INTEGER,INTEGER);
  1312.   function "<" is new BINARY_OPERATOR(O_LT,FLOAT,  FLOAT);
  1313.   function "<" is new BINARY_OPERATOR(O_LT,STRING, STRING);
  1314.   function "<" is new BINARY_OPERATOR(O_LT,INTEGER,FLOAT);
  1315.   function "<" is new BINARY_OPERATOR(O_LT,FLOAT,  INTEGER);
  1316.   function "<" is new BINARY_OPERATOR(O_LT,FIELD,  INTEGER);
  1317.   function "<" is new BINARY_OPERATOR(O_LT,FIELD,  FLOAT);
  1318.   function "<" is new BINARY_OPERATOR(O_LT,FIELD,  STRING);
  1319.   function "<" is new BINARY_OPERATOR(O_LT,INTEGER,FIELD);
  1320.   function "<" is new BINARY_OPERATOR(O_LT,FLOAT,  FIELD);
  1321.   function "<" is new BINARY_OPERATOR(O_LT,STRING, FIELD);
  1322.  
  1323.   function "<=" is new BINARY_OPERATOR(O_LE,FIELD,  FIELD);
  1324.   function "<=" is new BINARY_OPERATOR(O_LE,INTEGER,INTEGER);
  1325.   function "<=" is new BINARY_OPERATOR(O_LE,FLOAT,  FLOAT);
  1326.   function "<=" is new BINARY_OPERATOR(O_LE,STRING, STRING);
  1327.   function "<=" is new BINARY_OPERATOR(O_LE,INTEGER,FLOAT);
  1328.   function "<=" is new BINARY_OPERATOR(O_LE,FLOAT,  INTEGER);
  1329.   function "<=" is new BINARY_OPERATOR(O_LE,FIELD,  INTEGER);
  1330.   function "<=" is new BINARY_OPERATOR(O_LE,FIELD,  FLOAT);
  1331.   function "<=" is new BINARY_OPERATOR(O_LE,FIELD,  STRING);
  1332.   function "<=" is new BINARY_OPERATOR(O_LE,INTEGER,FIELD);
  1333.   function "<=" is new BINARY_OPERATOR(O_LE,FLOAT,  FIELD);
  1334.   function "<=" is new BINARY_OPERATOR(O_LE,STRING, FIELD);
  1335.  
  1336.   function ">" is new BINARY_OPERATOR(O_GT,FIELD,  FIELD);
  1337.   function ">" is new BINARY_OPERATOR(O_GT,INTEGER,INTEGER);
  1338.   function ">" is new BINARY_OPERATOR(O_GT,FLOAT,  FLOAT);
  1339.   function ">" is new BINARY_OPERATOR(O_GT,STRING, STRING);
  1340.   function ">" is new BINARY_OPERATOR(O_GT,INTEGER,FLOAT);
  1341.   function ">" is new BINARY_OPERATOR(O_GT,FLOAT,  INTEGER);
  1342.   function ">" is new BINARY_OPERATOR(O_GT,FIELD,  INTEGER);
  1343.   function ">" is new BINARY_OPERATOR(O_GT,FIELD,  FLOAT);
  1344.   function ">" is new BINARY_OPERATOR(O_GT,FIELD,  STRING);
  1345.   function ">" is new BINARY_OPERATOR(O_GT,INTEGER,FIELD);
  1346.   function ">" is new BINARY_OPERATOR(O_GT,FLOAT,  FIELD);
  1347.   function ">" is new BINARY_OPERATOR(O_GT,STRING, FIELD);
  1348.  
  1349.   function ">=" is new BINARY_OPERATOR(O_GE,FIELD,  FIELD);
  1350.   function ">=" is new BINARY_OPERATOR(O_GE,INTEGER,INTEGER);
  1351.   function ">=" is new BINARY_OPERATOR(O_GE,FLOAT,  FLOAT);
  1352.   function ">=" is new BINARY_OPERATOR(O_GE,STRING, STRING);
  1353.   function ">=" is new BINARY_OPERATOR(O_GE,INTEGER,FLOAT);
  1354.   function ">=" is new BINARY_OPERATOR(O_GE,FLOAT,  INTEGER);
  1355.   function ">=" is new BINARY_OPERATOR(O_GE,FIELD,  INTEGER);
  1356.   function ">=" is new BINARY_OPERATOR(O_GE,FIELD,  FLOAT);
  1357.   function ">=" is new BINARY_OPERATOR(O_GE,FIELD,  STRING);
  1358.   function ">=" is new BINARY_OPERATOR(O_GE,INTEGER,FIELD);
  1359.   function ">=" is new BINARY_OPERATOR(O_GE,FLOAT,  FIELD);
  1360.   function ">=" is new BINARY_OPERATOR(O_GE,STRING, FIELD);
  1361.  
  1362.   function "+" is new BINARY_OPERATOR(O_PLUS,FIELD,  FIELD);
  1363.   function "+" is new BINARY_OPERATOR(O_PLUS,INTEGER,INTEGER);
  1364.   function "+" is new BINARY_OPERATOR(O_PLUS,FLOAT,  FLOAT);
  1365.   function "+" is new BINARY_OPERATOR(O_PLUS,INTEGER,FLOAT);
  1366.   function "+" is new BINARY_OPERATOR(O_PLUS,FLOAT,  INTEGER);
  1367.   function "+" is new BINARY_OPERATOR(O_PLUS,FIELD,  INTEGER);
  1368.   function "+" is new BINARY_OPERATOR(O_PLUS,FIELD,  FLOAT);
  1369.   function "+" is new BINARY_OPERATOR(O_PLUS,INTEGER,FIELD);
  1370.   function "+" is new BINARY_OPERATOR(O_PLUS,FLOAT,  FIELD);
  1371.  
  1372.   function "-" is new BINARY_OPERATOR(O_MINUS,FIELD,  FIELD);
  1373.   function "-" is new BINARY_OPERATOR(O_MINUS,INTEGER,INTEGER);
  1374.   function "-" is new BINARY_OPERATOR(O_MINUS,FLOAT,  FLOAT);
  1375.   function "-" is new BINARY_OPERATOR(O_MINUS,INTEGER,FLOAT);
  1376.   function "-" is new BINARY_OPERATOR(O_MINUS,FLOAT,  INTEGER);
  1377.   function "-" is new BINARY_OPERATOR(O_MINUS,FIELD,  INTEGER);
  1378.   function "-" is new BINARY_OPERATOR(O_MINUS,FIELD,  FLOAT);
  1379.   function "-" is new BINARY_OPERATOR(O_MINUS,INTEGER,FIELD);
  1380.   function "-" is new BINARY_OPERATOR(O_MINUS,FLOAT,  FIELD);
  1381.  
  1382.   function "&"(L : TABLE; R : TABLE) return TABLE renames SQL_DEFINITIONS."&";
  1383.  
  1384.   function "&" is new BINARY_OPERATOR(O_CAT,FIELD,  FIELD);
  1385.   function "&" is new BINARY_OPERATOR(O_CAT,INTEGER,INTEGER);
  1386.   function "&" is new BINARY_OPERATOR(O_CAT,FLOAT,  FLOAT);
  1387.   function "&" is new BINARY_OPERATOR(O_CAT,STRING, STRING);
  1388.   function "&" is new BINARY_OPERATOR(O_CAT,INTEGER,FLOAT);
  1389.   function "&" is new BINARY_OPERATOR(O_CAT,INTEGER,STRING);
  1390.   function "&" is new BINARY_OPERATOR(O_CAT,FLOAT,  INTEGER);
  1391.   function "&" is new BINARY_OPERATOR(O_CAT,FLOAT,  STRING);
  1392.   function "&" is new BINARY_OPERATOR(O_CAT,STRING, INTEGER);
  1393.   function "&" is new BINARY_OPERATOR(O_CAT,STRING, FLOAT);
  1394.   function "&" is new BINARY_OPERATOR(O_CAT,INTEGER,FIELD);
  1395.   function "&" is new BINARY_OPERATOR(O_CAT,FLOAT,  FIELD);
  1396.   function "&" is new BINARY_OPERATOR(O_CAT,STRING, FIELD);
  1397.   function "&" is new BINARY_OPERATOR(O_CAT,FIELD,  INTEGER);
  1398.   function "&" is new BINARY_OPERATOR(O_CAT,FIELD,  FLOAT);
  1399.   function "&" is new BINARY_OPERATOR(O_CAT,FIELD,  STRING);
  1400.  
  1401.   function "+" is new UNARY_OPERATOR(O_UNARY_PLUS,FIELD);
  1402.   function "+" is new UNARY_OPERATOR(O_UNARY_PLUS,INTEGER);
  1403.   function "+" is new UNARY_OPERATOR(O_UNARY_PLUS,FLOAT);
  1404.  
  1405.   function "-" is new UNARY_OPERATOR(O_UNARY_MINUS,FIELD);
  1406.   function "-" is new UNARY_OPERATOR(O_UNARY_MINUS,INTEGER);
  1407.   function "-" is new UNARY_OPERATOR(O_UNARY_MINUS,FLOAT);
  1408.  
  1409.   function "*" is new BINARY_OPERATOR(O_TIMES,FIELD,  FIELD);
  1410.   function "*" is new BINARY_OPERATOR(O_TIMES,INTEGER,INTEGER);
  1411.   function "*" is new BINARY_OPERATOR(O_TIMES,FLOAT,  FLOAT);
  1412.   function "*" is new BINARY_OPERATOR(O_TIMES,INTEGER,FLOAT);
  1413.   function "*" is new BINARY_OPERATOR(O_TIMES,FLOAT,  INTEGER);
  1414.   function "*" is new BINARY_OPERATOR(O_TIMES,FIELD,  INTEGER);
  1415.   function "*" is new BINARY_OPERATOR(O_TIMES,FIELD,  FLOAT);
  1416.   function "*" is new BINARY_OPERATOR(O_TIMES,INTEGER,FIELD);
  1417.   function "*" is new BINARY_OPERATOR(O_TIMES,FLOAT,  FIELD);
  1418.  
  1419.   function "/" is new BINARY_OPERATOR(O_DIV,FIELD,  FIELD);
  1420.   function "/" is new BINARY_OPERATOR(O_DIV,INTEGER,INTEGER);
  1421.   function "/" is new BINARY_OPERATOR(O_DIV,FLOAT,  FLOAT);
  1422.   function "/" is new BINARY_OPERATOR(O_DIV,INTEGER,FLOAT);
  1423.   function "/" is new BINARY_OPERATOR(O_DIV,FLOAT,  INTEGER);
  1424.   function "/" is new BINARY_OPERATOR(O_DIV,FIELD,  INTEGER);
  1425.   function "/" is new BINARY_OPERATOR(O_DIV,FIELD,  FLOAT);
  1426.   function "/" is new BINARY_OPERATOR(O_DIV,INTEGER,FIELD);
  1427.   function "/" is new BINARY_OPERATOR(O_DIV,FLOAT,  FIELD);
  1428.  
  1429.   function "mod" is new BINARY_OPERATOR(O_MOD,FIELD,  FIELD);
  1430.   function "mod" is new BINARY_OPERATOR(O_MOD,INTEGER,INTEGER);
  1431.   function "mod" is new BINARY_OPERATOR(O_MOD,FIELD,  INTEGER);
  1432.   function "mod" is new BINARY_OPERATOR(O_MOD,INTEGER,FIELD);
  1433.  
  1434.   function "rem" is new BINARY_OPERATOR(O_REM,FIELD,  FIELD);
  1435.   function "rem" is new BINARY_OPERATOR(O_REM,INTEGER,INTEGER);
  1436.   function "rem" is new BINARY_OPERATOR(O_REM,FIELD,  INTEGER);
  1437.   function "rem" is new BINARY_OPERATOR(O_REM,INTEGER,FIELD);
  1438.  
  1439.   function "**" is new BINARY_OPERATOR(O_POWER,FIELD,  FIELD);
  1440.   function "**" is new BINARY_OPERATOR(O_POWER,INTEGER,INTEGER);
  1441.   function "**" is new BINARY_OPERATOR(O_POWER,FLOAT,  INTEGER);
  1442.   function "**" is new BINARY_OPERATOR(O_POWER,FIELD,  INTEGER);
  1443.   function "**" is new BINARY_OPERATOR(O_POWER,INTEGER,FIELD);
  1444.   function "**" is new BINARY_OPERATOR(O_POWER,FLOAT,  FIELD);
  1445.  
  1446.   function "abs" is new UNARY_OPERATOR(O_ABS,FIELD);
  1447.   function "abs" is new UNARY_OPERATOR(O_ABS,INTEGER);
  1448.   function "abs" is new UNARY_OPERATOR(O_ABS,FLOAT);
  1449.  
  1450.   function "not" is new UNARY_OPERATOR(O_NOT,FIELD);
  1451.  
  1452.   subtype DATABASE_TYPE is SQL_DEFINITIONS.DATABASE_TYPE;
  1453.   subtype CURSOR_TYPE   is SQL_DEFINITIONS.CURSOR_TYPE;
  1454.   subtype FIELD_INDEX   is SQL_DEFINITIONS.FIELD_INDEX;
  1455.  
  1456.   function EXECUTE(F : FIELD) return CURSOR_TYPE
  1457.       renames SQL_DEFINITIONS.EXECUTE;
  1458.  
  1459.   procedure EXECUTE(F : in FIELD) renames SQL_DEFINITIONS.EXECUTE;
  1460.   procedure LIST   (F : in FIELD) renames SQL_DEFINITIONS.LIST;
  1461.   procedure SHOW   (F : in FIELD) renames SQL_DEFINITIONS.SHOW;
  1462.  
  1463.   procedure SET_DATABASE(DB : in DATABASE_TYPE)
  1464.       renames SQL_DEFINITIONS.SET_DATABASE;
  1465.  
  1466.   procedure NEXT_RECORD(CURSOR : in out CURSOR_TYPE)
  1467.       renames SQL_DEFINITIONS.NEXT_RECORD;
  1468.  
  1469.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  1470.                   FIELD  : in  FIELD_INDEX;
  1471.                   INT    : out INTEGER) renames SQL_DEFINITIONS.FETCH;
  1472.  
  1473.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  1474.                   FIELD  : in  FIELD_INDEX;
  1475.                   FLT    : out FLOAT) renames SQL_DEFINITIONS.FETCH;
  1476.  
  1477.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  1478.                   FIELD  : in  FIELD_INDEX;
  1479.                   STR    : out STRING;
  1480.                   LAST   : out NATURAL) renames SQL_DEFINITIONS.FETCH;
  1481.  
  1482.   function FETCH(CURSOR : CURSOR_TYPE;
  1483.                  FIELD  : FIELD_INDEX) return INTEGER
  1484.       renames SQL_DEFINITIONS.FETCH;
  1485.  
  1486.   function FETCH(CURSOR : CURSOR_TYPE;
  1487.                  FIELD  : FIELD_INDEX) return FLOAT
  1488.       renames SQL_DEFINITIONS.FETCH;
  1489.  
  1490.   function FETCH(CURSOR : CURSOR_TYPE;
  1491.                  FIELD  : FIELD_INDEX) return STRING
  1492.       renames SQL_DEFINITIONS.FETCH;
  1493.  
  1494.   function LOAD_DATABASE(FILE_NAME : in STRING) return DATABASE_TYPE
  1495.       renames SQL_DEFINITIONS.LOAD_DATABASE;
  1496.  
  1497.   procedure SAVE_DATABASE(FILE_NAME : in STRING;
  1498.                           DATABASE  : in DATABASE_TYPE)
  1499.       renames SQL_DEFINITIONS.SAVE_DATABASE;
  1500.  
  1501.   CALL_ERROR          : exception renames SQL_DEFINITIONS.CALL_ERROR;
  1502.   DONE_ERROR          : exception renames SQL_DEFINITIONS.DONE_ERROR;
  1503.   FIELD_ERROR         : exception renames SQL_DEFINITIONS.FIELD_ERROR;
  1504.   SYNTAX_ERROR        : exception renames SQL_DEFINITIONS.SYNTAX_ERROR;
  1505.   TABLE_ERROR         : exception renames SQL_DEFINITIONS.TABLE_ERROR;
  1506.   TRUNCATE_ERROR      : exception renames SQL_DEFINITIONS.TRUNCATE_ERROR;
  1507.   TYPE_ERROR          : exception renames SQL_DEFINITIONS.TYPE_ERROR;
  1508.   UNIMPLEMENTED_ERROR : exception renames SQL_DEFINITIONS.UNIMPLEMENTED_ERROR;
  1509.  
  1510. end SQL_OPERATIONS;
  1511.  
  1512. with SQL_DEFINITIONS;
  1513.   use SQL_DEFINITIONS;
  1514.  
  1515. package body SQL_OPERATIONS is
  1516.  
  1517.   function SELEC(WHAT   : STAR_TYPE;
  1518.                  FROM   : TABLE := NULL_TABLE;
  1519.                  WHERE  : FIELD := NULL_FIELD;
  1520.                  GROUP  : FIELD := NULL_FIELD;
  1521.                  HAVING : FIELD := NULL_FIELD;
  1522.                  ORDER  : FIELD := NULL_FIELD) return FIELD is
  1523.   begin
  1524.     return SELEC(STAR,FROM,WHERE,GROUP,HAVING,ORDER);
  1525.   end SELEC;
  1526.  
  1527.   function COUNT(X : STAR_TYPE) return FIELD is
  1528.   begin
  1529.     return COUNT(STAR);
  1530.   end COUNT;
  1531.  
  1532. end SQL_OPERATIONS;
  1533. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1534. --dateund.ada
  1535. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1536. with SQL_DEFINITIONS;
  1537.   use SQL_DEFINITIONS;
  1538.  
  1539. package DATE_UNDERLYING is
  1540.  
  1541.   type CELLAR_TYPE is
  1542.     record
  1543.       STAR, BIN, WINE, PRODUCER, YEAR, BOTTLES, READY, COMMENTS : FIELD;
  1544.     end record;
  1545.  
  1546.   type FLIGHTS_TYPE is
  1547.     record
  1548.       STAR, FLIGHT, FROM_CODE, TO_CODE, DEP_TIME, ARR_TIME : FIELD;
  1549.     end record;
  1550.  
  1551.   type CITIES_TYPE is
  1552.     record
  1553.       STAR, CODE, CITY : FIELD;
  1554.     end record;
  1555.  
  1556.   type PARCELS_TYPE is
  1557.     record
  1558.       STAR, APN, ROAD, OWNER, IMPROVED, LAST_ENTRY, BALANCE : FIELD;
  1559.     end record;
  1560.  
  1561.   type OWNERS_TYPE is
  1562.     record
  1563.       STAR, OWNER, ADDRESS, PHONE : FIELD;
  1564.     end record;
  1565.  
  1566.   type PARCEL_ACCOUNTS_TYPE is
  1567.     record
  1568.       STAR, APN, EN_TRY, DATE, DESCRIPTION, TYP, AMOUNT, BALANCE : FIELD;
  1569.     end record;
  1570.  
  1571.   type SPECIAL_ASSESSMENTS_TYPE is
  1572.     record
  1573.       STAR, SAN, ROAD, DATE, TOTAL, PER_PARCEL, EXPLANATION, PAYEE : FIELD;
  1574.     end record;
  1575.  
  1576.   type LEDGER_TYPE is
  1577.     record
  1578.       STAR, EN_TRY, DATE, DESCRIPTION, TYP, PARTY, AMOUNT, BALANCE : FIELD;
  1579.     end record;
  1580.  
  1581.   type GENERAL_LEDGER_TYPE is new LEDGER_TYPE;
  1582.   type REDWOOD_LEDGER_TYPE is new LEDGER_TYPE;
  1583.   type CREEK_LEDGER_TYPE   is new LEDGER_TYPE;
  1584.   type MILL_LEDGER_TYPE    is new LEDGER_TYPE;
  1585.  
  1586.   type LAST_ENTRIES_TYPE is
  1587.     record
  1588.       STAR, ACCOUNT, EN_TRY, BALANCE : FIELD;
  1589.     end record;
  1590.  
  1591.   type CELLAR_TABLE              is access CELLAR_TYPE;
  1592.   type FLIGHTS_TABLE             is access FLIGHTS_TYPE;
  1593.   type CITIES_TABLE              is access CITIES_TYPE;
  1594.   type PARCELS_TABLE             is access PARCELS_TYPE;
  1595.   type OWNERS_TABLE              is access OWNERS_TYPE;
  1596.   type PARCEL_ACCOUNTS_TABLE     is access PARCEL_ACCOUNTS_TYPE;
  1597.   type SPECIAL_ASSESSMENTS_TABLE is access SPECIAL_ASSESSMENTS_TYPE;
  1598.   type GENERAL_LEDGER_TABLE      is access GENERAL_LEDGER_TYPE;
  1599.   type REDWOOD_LEDGER_TABLE      is access REDWOOD_LEDGER_TYPE;
  1600.   type CREEK_LEDGER_TABLE        is access CREEK_LEDGER_TYPE;
  1601.   type MILL_LEDGER_TABLE         is access MILL_LEDGER_TYPE;
  1602.   type LAST_ENTRIES_TABLE        is access LAST_ENTRIES_TYPE;
  1603.  
  1604.   BIN         : constant FIELD := MAKE_FIELD("BIN");
  1605.   WINE        : constant FIELD := MAKE_FIELD("WINE");
  1606.   PRODUCER    : constant FIELD := MAKE_FIELD("PRODUCER");
  1607.   YEAR        : constant FIELD := MAKE_FIELD("YEAR");
  1608.   BOTTLES     : constant FIELD := MAKE_FIELD("BOTTLES");
  1609.   READY       : constant FIELD := MAKE_FIELD("READY");
  1610.   COMMENTS    : constant FIELD := MAKE_FIELD("COMMENTS");
  1611.   FLIGHT      : constant FIELD := MAKE_FIELD("FLIGHT");
  1612.   FROM_CODE   : constant FIELD := MAKE_FIELD("FROM_CODE");
  1613.   TO_CODE     : constant FIELD := MAKE_FIELD("TO_CODE");
  1614.   DEP_TIME    : constant FIELD := MAKE_FIELD("DEP_TIME");
  1615.   ARR_TIME    : constant FIELD := MAKE_FIELD("ARR_TIME");
  1616.   CODE        : constant FIELD := MAKE_FIELD("CODE");
  1617.   CITY        : constant FIELD := MAKE_FIELD("CITY");
  1618.   APN         : constant FIELD := MAKE_FIELD("APN");
  1619.   ROAD        : constant FIELD := MAKE_FIELD("ROAD");
  1620.   OWNER       : constant FIELD := MAKE_FIELD("OWNER");
  1621.   IMPROVED    : constant FIELD := MAKE_FIELD("IMPROVED");
  1622.   LAST_ENTRY  : constant FIELD := MAKE_FIELD("LAST_ENTRY");
  1623.   BALANCE     : constant FIELD := MAKE_FIELD("BALANCE");
  1624.   ADDRESS     : constant FIELD := MAKE_FIELD("ADDRESS");
  1625.   PHONE       : constant FIELD := MAKE_FIELD("PHONE");
  1626.   EN_TRY      : constant FIELD := MAKE_FIELD("ENTRY");
  1627.   DATE        : constant FIELD := MAKE_FIELD("DATE");
  1628.   DESCRIPTION : constant FIELD := MAKE_FIELD("DESCRIPTION");
  1629.   TYP         : constant FIELD := MAKE_FIELD("TYPE");
  1630.   AMOUNT      : constant FIELD := MAKE_FIELD("AMOUNT");
  1631.   SAN         : constant FIELD := MAKE_FIELD("SAN");
  1632.   TOTAL       : constant FIELD := MAKE_FIELD("TOTAL");
  1633.   PER_PARCEL  : constant FIELD := MAKE_FIELD("PER_PARCEL");
  1634.   EXPLANATION : constant FIELD := MAKE_FIELD("EXPLANATION");
  1635.   PAYEE       : constant FIELD := MAKE_FIELD("PAYEE");
  1636.   PARTY       : constant FIELD := MAKE_FIELD("PARTY");
  1637.   ACCOUNT     : constant FIELD := MAKE_FIELD("ACCOUNT");
  1638.  
  1639.   CELLAR_DATA              : CELLAR_TABLE;
  1640.   FLIGHTS_DATA             : FLIGHTS_TABLE;
  1641.   CITIES_DATA              : CITIES_TABLE;
  1642.   PARCELS_DATA             : PARCELS_TABLE;
  1643.   OWNERS_DATA              : OWNERS_TABLE;
  1644.   PARCEL_ACCOUNTS_DATA     : PARCEL_ACCOUNTS_TABLE;
  1645.   SPECIAL_ASSESSMENTS_DATA : SPECIAL_ASSESSMENTS_TABLE;
  1646.   GENERAL_LEDGER_DATA      : GENERAL_LEDGER_TABLE;
  1647.   REDWOOD_LEDGER_DATA      : REDWOOD_LEDGER_TABLE;
  1648.   CREEK_LEDGER_DATA        : CREEK_LEDGER_TABLE;
  1649.   MILL_LEDGER_DATA         : MILL_LEDGER_TABLE;
  1650.   LAST_ENTRIES_DATA        : LAST_ENTRIES_TABLE;
  1651.  
  1652.   procedure CELLAR             (X : in out CELLAR_TABLE);
  1653.   procedure FLIGHTS            (X : in out FLIGHTS_TABLE);
  1654.   procedure CITIES             (X : in out CITIES_TABLE);
  1655.   procedure PARCELS            (X : in out PARCELS_TABLE);
  1656.   procedure OWNERS             (X : in out OWNERS_TABLE);
  1657.   procedure PARCEL_ACCOUNTS    (X : in out PARCEL_ACCOUNTS_TABLE);
  1658.   procedure SPECIAL_ASSESSMENTS(X : in out SPECIAL_ASSESSMENTS_TABLE);
  1659.   procedure GENERAL_LEDGER     (X : in out GENERAL_LEDGER_TABLE);
  1660.   procedure REDWOOD_LEDGER     (X : in out REDWOOD_LEDGER_TABLE);
  1661.   procedure CREEK_LEDGER       (X : in out CREEK_LEDGER_TABLE);
  1662.   procedure MILL_LEDGER        (X : in out MILL_LEDGER_TABLE);
  1663.   procedure LAST_ENTRIES       (X : in out LAST_ENTRIES_TABLE);
  1664.  
  1665. end DATE_UNDERLYING;
  1666.  
  1667. with SQL_DEFINITIONS;
  1668.   use SQL_DEFINITIONS;
  1669.  
  1670. package body DATE_UNDERLYING is
  1671.  
  1672.   procedure CELLAR(X : in out CELLAR_TABLE) is
  1673.     T : TABLE_NAME;
  1674.   begin
  1675.     if X = null then
  1676.       T := MAKE_TABLE_NAME("CELLAR");
  1677.       X := new CELLAR_TYPE'(
  1678.         MAKE_FIELD(T,STAR),
  1679.         MAKE_FIELD(T,BIN),
  1680.         MAKE_FIELD(T,WINE),
  1681.         MAKE_FIELD(T,PRODUCER),
  1682.         MAKE_FIELD(T,YEAR),
  1683.         MAKE_FIELD(T,BOTTLES),
  1684.         MAKE_FIELD(T,READY),
  1685.         MAKE_FIELD(T,COMMENTS) );
  1686.     end if;
  1687.   end CELLAR;
  1688.  
  1689.   procedure FLIGHTS(X : in out FLIGHTS_TABLE) is
  1690.     T : TABLE_NAME;
  1691.   begin
  1692.     if X = null then
  1693.       T := MAKE_TABLE_NAME("FLIGHTS");
  1694.       X := new FLIGHTS_TYPE'(
  1695.         MAKE_FIELD(T,STAR),
  1696.         MAKE_FIELD(T,FLIGHT),
  1697.         MAKE_FIELD(T,FROM_CODE),
  1698.         MAKE_FIELD(T,TO_CODE),
  1699.         MAKE_FIELD(T,DEP_TIME),
  1700.         MAKE_FIELD(T,ARR_TIME) );
  1701.     end if;
  1702.   end FLIGHTS;
  1703.  
  1704.   procedure CITIES(X : in out CITIES_TABLE) is
  1705.     T : TABLE_NAME;
  1706.   begin
  1707.     if X = null then
  1708.       T := MAKE_TABLE_NAME("CITIES");
  1709.       X := new CITIES_TYPE'(
  1710.         MAKE_FIELD(T,STAR),
  1711.         MAKE_FIELD(T,CODE),
  1712.         MAKE_FIELD(T,CITY) );
  1713.     end if;
  1714.   end CITIES;
  1715.  
  1716.   procedure PARCELS(X : in out PARCELS_TABLE) is
  1717.     T : TABLE_NAME;
  1718.   begin
  1719.     if X = null then
  1720.       T := MAKE_TABLE_NAME("PARCELS");
  1721.       X := new PARCELS_TYPE'(
  1722.         MAKE_FIELD(T,STAR),
  1723.         MAKE_FIELD(T,APN),
  1724.         MAKE_FIELD(T,ROAD),
  1725.         MAKE_FIELD(T,OWNER),
  1726.         MAKE_FIELD(T,IMPROVED),
  1727.         MAKE_FIELD(T,LAST_ENTRY),
  1728.         MAKE_FIELD(T,BALANCE) );
  1729.     end if;
  1730.   end PARCELS;
  1731.  
  1732.   procedure OWNERS(X : in out OWNERS_TABLE) is
  1733.     T : TABLE_NAME;
  1734.   begin
  1735.     if X = null then
  1736.       T := MAKE_TABLE_NAME("OWNERS");
  1737.       X := new OWNERS_TYPE'(
  1738.         MAKE_FIELD(T,STAR),
  1739.         MAKE_FIELD(T,OWNER),
  1740.         MAKE_FIELD(T,ADDRESS),
  1741.         MAKE_FIELD(T,PHONE) );
  1742.     end if;
  1743.   end OWNERS;
  1744.  
  1745.   procedure PARCEL_ACCOUNTS(X : in out PARCEL_ACCOUNTS_TABLE) is
  1746.     T : TABLE_NAME;
  1747.   begin
  1748.     if X = null then
  1749.       T := MAKE_TABLE_NAME("PARCEL_ACCOUNTS");
  1750.       X := new PARCEL_ACCOUNTS_TYPE'(
  1751.         MAKE_FIELD(T,STAR),
  1752.         MAKE_FIELD(T,APN),
  1753.         MAKE_FIELD(T,EN_TRY),
  1754.         MAKE_FIELD(T,DATE),
  1755.         MAKE_FIELD(T,DESCRIPTION),
  1756.         MAKE_FIELD(T,TYP),
  1757.         MAKE_FIELD(T,AMOUNT),
  1758.         MAKE_FIELD(T,BALANCE) );
  1759.     end if;
  1760.   end PARCEL_ACCOUNTS;
  1761.  
  1762.   procedure SPECIAL_ASSESSMENTS(X : in out SPECIAL_ASSESSMENTS_TABLE) is
  1763.     T : TABLE_NAME;
  1764.   begin
  1765.     if X = null then
  1766.       T := MAKE_TABLE_NAME("SPECIAL_ASSESSMENTS");
  1767.       X := new SPECIAL_ASSESSMENTS_TYPE'(
  1768.         MAKE_FIELD(T,STAR),
  1769.         MAKE_FIELD(T,SAN),
  1770.         MAKE_FIELD(T,ROAD),
  1771.         MAKE_FIELD(T,DATE),
  1772.         MAKE_FIELD(T,TOTAL),
  1773.         MAKE_FIELD(T,PER_PARCEL),
  1774.         MAKE_FIELD(T,EXPLANATION),
  1775.         MAKE_FIELD(T,PAYEE) );
  1776.     end if;
  1777.   end SPECIAL_ASSESSMENTS;
  1778.  
  1779.   procedure GENERAL_LEDGER(X : in out GENERAL_LEDGER_TABLE) is
  1780.     T : TABLE_NAME;
  1781.   begin
  1782.     if X = null then
  1783.       T := MAKE_TABLE_NAME("GENERAL_LEDGER");
  1784.       X := new GENERAL_LEDGER_TYPE'(
  1785.         MAKE_FIELD(T,STAR),
  1786.         MAKE_FIELD(T,EN_TRY),
  1787.         MAKE_FIELD(T,DATE),
  1788.         MAKE_FIELD(T,DESCRIPTION),
  1789.         MAKE_FIELD(T,TYP),
  1790.         MAKE_FIELD(T,PARTY),
  1791.         MAKE_FIELD(T,AMOUNT),
  1792.         MAKE_FIELD(T,BALANCE) );
  1793.     end if;
  1794.   end GENERAL_LEDGER;
  1795.  
  1796.   procedure REDWOOD_LEDGER(X : in out REDWOOD_LEDGER_TABLE) is
  1797.     T : TABLE_NAME;
  1798.   begin
  1799.     if X = null then
  1800.       T := MAKE_TABLE_NAME("REDWOOD_LEDGER");
  1801.       X := new RED_FIELD(T,EN_TRY),
  1802.         MAKE_FIELD(T,DATE),
  1803.         MAKE_FIELD(T,DESCRIPTION),
  1804.         MAKE_FIELD(T,TYP),
  1805.         MAKE_FIELD(T,PARTY),
  1806.         MAKE_FIELD(T,AMOUNT),
  1807.         MAKE_FIELD(T,BALANCE) );
  1808.     end if;
  1809.   end REDWOOD_LEDGER;
  1810.  
  1811.   procedure CREEK_LEDGER(X : in out CREEK_LEDGER_TABLE) is
  1812.     T : TABLE_NAME;
  1813.   begin
  1814.     if X = null then
  1815.       T := MAKE_TABLE_NAME("CREEK_LEDGER");
  1816.       X := new CREEK_LEDGER_TYPE'(
  1817.         MAKE_FIELD(T,STAR),
  1818.         MAKE_FIELD(T,EN_TRY),
  1819.         MAKE_FIELD(T,DATE),
  1820.         MAKE_FIELD(T,DESCRIPTION),
  1821.         MAKE_FIELD(T,TYP),
  1822.         MAKE_FIELD(T,PARTY),
  1823.         MAKE_FIELD(T,AMOUNT),
  1824.         MAKE_FIELD(T,BALANCE) );
  1825.     end if;
  1826.   end CREEK_LEDGER;
  1827.  
  1828.   procedure MILL_LEDGER(X : in out MILL_LEDGER_TABLE) is
  1829.     T : TABLE_NAME;
  1830.   begin
  1831.     if X = null then
  1832.       T := MAKE_TABLE_NAME("MILL_LEDGER");
  1833.       X := new MILL_LEDGER_TYPE'(
  1834.         MAKE_FIELD(T,STAR),
  1835.         MAKE_FIELD(T,EN_TRY),
  1836.         MAKE_FIELD(T,DATE),
  1837.         MAKE_FIELD(T,DESCRIPTION),
  1838.         MAKE_FIELD(T,TYP),
  1839.         MAKE_FIELD(T,PARTY),
  1840.         MAKE_FIELD(T,AMOUNT),
  1841.         MAKE_FIELD(T,BALANCE) );
  1842.     end if;
  1843.   end MILL_LEDGER;
  1844.  
  1845.   procedure LAST_ENTRIES(X : in out LAST_ENTRIES_TABLE) is
  1846.     T : TABLE_NAME;
  1847.   begin
  1848.     if X = null then
  1849.       T := MAKE_TABLE_NAME("LAST_ENTRIES");
  1850.       X := new LAST_ENTRIES_TYPE'(
  1851.         MAKE_FIELD(T,STAR),
  1852.         MAKE_FIELD(T,ACCOUNT),
  1853.         MAKE_FIELD(T,EN_TRY),
  1854.         MAKE_FIELD(T,BALANCE) );
  1855.     end if;
  1856.   end LAST_ENTRIES;
  1857.  
  1858. begin
  1859.  
  1860.   CELLAR             (CELLAR_DATA);
  1861.   FLIGHTS            (FLIGHTS_DATA);
  1862.   CITIES             (CITIES_DATA);
  1863.   PARCELS            (PARCELS_DATA);
  1864.   OWNERS             (OWNERS_DATA);
  1865.   PARCEL_ACCOUNTS    (PARCEL_ACCOUNTS_DATA);
  1866.   SPECIAL_ASSESSMENTS(SPECIAL_ASSESSMENTS_DATA);
  1867.   GENERAL_LEDGER     (GENERAL_LEDGER_DATA);
  1868.   REDWOOD_LEDGER     (REDWOOD_LEDGER_DATA);
  1869.   CREEK_LEDGER       (CREEK_LEDGER_DATA);
  1870.   MILL_LEDGER        (MILL_LEDGER_DATA);
  1871.   LAST_ENTRIES       (LAST_ENTRIES_DATA);
  1872.  
  1873. end DATE_UNDERLYING;
  1874. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1875. --datedb.ada
  1876. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1877. with SQL_DEFINITIONS, DATE_UNDERLYING;
  1878.   use SQL_DEFINITIONS, DATE_UNDERLYING;
  1879.  
  1880. package DATE_DATABASE is
  1881.  
  1882.   subtype CELLAR_TYPE              is DATE_UNDERLYING.CELLAR_TYPE;
  1883.   subtype FLIGHTS_TYPE             is DATE_UNDERLYING.FLIGHTS_TYPE;
  1884.   subtype CITIES_TYPE              is DATE_UNDERLYING.CITIES_TYPE;
  1885.   subtype PARCELS_TYPE             is DATE_UNDERLYING.PARCELS_TYPE;
  1886.   subtype OWNERS_TYPE              is DATE_UNDERLYING.OWNERS_TYPE;
  1887.   subtype PARCEL_ACCOUNTS_TYPE     is DATE_UNDERLYING.PARCEL_ACCOUNTS_TYPE;
  1888.   subtype SPECIAL_ASSESSMENTS_TYPE is DATE_UNDERLYING.SPECIAL_ASSESSMENTS_TYPE;
  1889.   subtype GENERAL_LEDGER_TYPE      is DATE_UNDERLYING.GENERAL_LEDGER_TYPE;
  1890.   subtype REDWOOD_LEDGER_TYPE      is DATE_UNDERLYING.REDWOOD_LEDGER_TYPE;
  1891.   subtype CREEK_LEDGER_TYPE        is DATE_UNDERLYING.CREEK_LEDGER_TYPE;
  1892.   subtype MILL_LEDGER_TYPE         is DATE_UNDERLYING.MILL_LEDGER_TYPE;
  1893.   subtype LAST_ENTRIES_TYPE        is DATE_UNDERLYING.LAST_ENTRIES_TYPE;
  1894.  
  1895.   subtype CELLAR_TABLE          is DATE_UNDERLYING.CELLAR_TABLE;
  1896.   subtype FLIGHTS_TABLE         is DATE_UNDERLYING.FLIGHTS_TABLE;
  1897.   subtype CITIES_TABLE          is DATE_UNDERLYING.CITIES_TABLE;
  1898.   subtype PARCELS_TABLE         is DATE_UNDERLYING.PARCELS_TABLE;
  1899.   subtype OWNERS_TABLE          is DATE_UNDERLYING.OWNERS_TABLE;
  1900.   subtype PARCEL_ACCOUNTS_TABLE is DATE_UNDERLYING.PARCEL_ACCOUNTS_TABLE;
  1901.   subtype SPECIAL_ASSESSMENTS_TABLE is
  1902.     DATE_UNDERLYING.SPECIAL_ASSESSMENTS_TABLE;
  1903.   subtype GENERAL_LEDGER_TABLE is DATE_UNDERLYING.GENERAL_LEDGER_TABLE;
  1904.   subtype REDWOOD_LEDGER_TABLE is DATE_UNDERLYING.REDWOOD_LEDGER_TABLE;
  1905.   subtype CREEK_LEDGER_TABLE   is DATE_UNDERLYING.CREEK_LEDGER_TABLE;
  1906.   subtype MILL_LEDGER_TABLE    is DATE_UNDERLYING.MILL_LEDGER_TABLE;
  1907.   subtype LAST_ENTRIES_TABLE   is DATE_UNDERLYING.LAST_ENTRIES_TABLE;
  1908.  
  1909.   BIN         : FIELD renames DATE_UNDERLYING.BIN;
  1910.   WINE        : FIELD renames DATE_UNDERLYING.WINE;
  1911.   PRODUCER    : FIELD renames DATE_UNDERLYING.PRODUCER;
  1912.   YEAR        : FIELD renames DATE_UNDERLYING.YEAR;
  1913.   BOTTLES     : FIELD renames DATE_UNDERLYING.BOTTLES;
  1914.   READY       : FIELD renames DATE_UNDERLYING.READY;
  1915.   COMMENTS    : FIELD renames DATE_UNDERLYING.COMMENTS;
  1916.   FLIGHT      : FIELD renames DATE_UNDERLYING.FLIGHT;
  1917.   FROM_CODE   : FIELD renames DATE_UNDERLYING.FROM_CODE;
  1918.   TO_CODE     : FIELD renames DATE_UNDERLYING.TO_CODE;
  1919.   DEP_TIME    : FIELD renames DATE_UNDERLYING.DEP_TIME;
  1920.   ARR_TIME    : FIELD renames DATE_UNDERLYING.ARR_TIME;
  1921.   CODE        : FIELD renames DATE_UNDERLYING.CODE;
  1922.   CITY        : FIELD renames DATE_UNDERLYING.CITY;
  1923.   APN         : FIELD renames DATE_UNDERLYING.APN;
  1924.   ROAD        : FIELD renames DATE_UNDERLYING.ROAD;
  1925.   OWNER       : FIELD renames DATE_UNDERLYING.OWNER;
  1926.   IMPROVED    : FIELD renames DATE_UNDERLYING.IMPROVED;
  1927.   LAST_ENTRY  : FIELD renames DATE_UNDERLYING.LAST_ENTRY;
  1928.   BALANCE     : FIELD renames DATE_UNDERLYING.BALANCE;
  1929.   ADDRESS     : FIELD renames DATE_UNDERLYING.ADDRESS;
  1930.   PHONE       : FIELD renames DATE_UNDERLYING.PHONE;
  1931.   EN_TRY      : FIELD renames DATE_UNDERLYING.EN_TRY;
  1932.   DATE        : FIELD renames DATE_UNDERLYING.DATE;
  1933.   DESCRIPTION : FIELD renames DATE_UNDERLYING.DESCRIPTION;
  1934.   TYP         : FIELD renames DATE_UNDERLYING.TYP;
  1935.   AMOUNT      : FIELD renames DATE_UNDERLYING.AMOUNT;
  1936.   SAN         : FIELD renames DATE_UNDERLYING.SAN;
  1937.   TOTAL       : FIELD renames DATE_UNDERLYING.TOTAL;
  1938.   PER_PARCEL  : FIELD renames DATE_UNDERLYING.PER_PARCEL;
  1939.   EXPLANATION : FIELD renames DATE_UNDERLYING.EXPLANATION;
  1940.   PAYEE       : FIELD renames DATE_UNDERLYING.PAYEE;
  1941.   PARTY       : FIELD renames DATE_UNDERLYING.PARTY;
  1942.   ACCOUNT     : FIELD renames DATE_UNDERLYING.ACCOUNT;
  1943.  
  1944.   function CELLAR              is new GET_TABLE(CELLAR_DATA.STAR);
  1945.   function FLIGHTS             is new GET_TABLE(FLIGHTS_DATA.STAR);
  1946.   function CITIES              is new GET_TABLE(CITIES_DATA.STAR);
  1947.   function PARCELS             is new GET_TABLE(PARCELS_DATA.STAR);
  1948.   function OWNERS              is new GET_TABLE(OWNERS_DATA.STAR);
  1949.   function PARCEL_ACCOUNTS     is new GET_TABLE(PARCEL_ACCOUNTS_DATA.STAR);
  1950.   function SPECIAL_ASSESSMENTS is new GET_TABLE(SPECIAL_ASSESSMENTS_DATA.STAR);
  1951.   function GENERAL_LEDGER      is new GET_TABLE(GENERAL_LEDGER_DATA.STAR);
  1952.   function REDWOOD_LEDGER      is new GET_TABLE(REDWOOD_LEDGER_DATA.STAR);
  1953.   function CREEK_LEDGER        is new GET_TABLE(CREEK_LEDGER_DATA.STAR);
  1954.   function MILL_LEDGER         is new GET_TABLE(MILL_LEDGER_DATA.STAR);
  1955.   function LAST_ENTRIES        is new GET_TABLE(LAST_ENTRIES_DATA.STAR);
  1956.  
  1957.   function CELLAR  is new GET_FIELDS(CELLAR_TABLE,CELLAR_DATA);
  1958.   function FLIGHTS is new GET_FIELDS(FLIGHTS_TABLE,FLIGHTS_DATA);
  1959.   function CITIES  is new GET_FIELDS(CITIES_TABLE,CITIES_DATA);
  1960.   function PARCELS is new GET_FIELDS(PARCELS_TABLE,PARCELS_DATA);
  1961.   function OWNERS  is new GET_FIELDS(OWNERS_TABLE,OWNERS_DATA);
  1962.   function PARCEL_ACCOUNTS is
  1963.     new GET_FIELDS(PARCEL_ACCOUNTS_TABLE,PARCEL_ACCOUNTS_DATA);
  1964.   function SPECIAL_ASSESSMENTS is
  1965.     new GET_FIELDS(SPECIAL_ASSESSMENTS_TABLE,SPECIAL_ASSESSMENTS_DATA);
  1966.   function GENERAL_LEDGER is
  1967.     new GET_FIELDS(GENERAL_LEDGER_TABLE,GENERAL_LEDGER_DATA);
  1968.   function REDWOOD_LEDGER is
  1969.     new GET_FIELDS(REDWOOD_LEDGER_TABLE,REDWOOD_LEDGER_DATA);
  1970.   function CREEK_LEDGER is
  1971.     new GET_FIELDS(CREEK_LEDGER_TABLE,CREEK_LEDGER_DATA);
  1972.   function MILL_LEDGER is
  1973.     new GET_FIELDS(MILL_LEDGER_TABLE,MILL_LEDGER_DATA);
  1974.   function LAST_ENTRIES is
  1975.     new GET_FIELDS(LAST_ENTRIES_TABLE,LAST_ENTRIES_DATA);
  1976.  
  1977.   function CELLAR          is new INSERT_FIELDS(CELLAR_DATA.STAR);
  1978.   function FLIGHTS         is new INSERT_FIELDS(FLIGHTS_DATA.STAR);
  1979.   function CITIES          is new INSERT_FIELDS(CITIES_DATA.STAR);
  1980.   function PARCELS         is new INSERT_FIELDS(PARCELS_DATA.STAR);
  1981.   function OWNERS          is new INSERT_FIELDS(OWNERS_DATA.STAR);
  1982.   function PARCEL_ACCOUNTS is new INSERT_FIELDS(PARCEL_ACCOUNTS_DATA.STAR);
  1983.   function SPECIAL_ASSESSMENTS is
  1984.     new INSERT_FIELDS(SPECIAL_ASSESSMENTS_DATA.STAR);
  1985.   function GENERAL_LEDGER is new INSERT_FIELDS(GENERAL_LEDGER_DATA.STAR);
  1986.   function REDWOOD_LEDGER is new INSERT_FIELDS(REDWOOD_LEDGER_DATA.STAR);
  1987.   function CREEK_LEDGER   is new INSERT_FIELDS(CREEK_LEDGER_DATA.STAR);
  1988.   function MILL_LEDGER    is new INSERT_FIELDS(MILL_LEDGER_DATA.STAR);
  1989.   function LAST_ENTRIES   is new INSERT_FIELDS(LAST_ENTRIES_DATA.STAR);
  1990.  
  1991.   procedure CELLAR (X : in out CELLAR_TABLE)  renames DATE_UNDERLYING.CELLAR;
  1992.   procedure FLIGHTS(X : in out FLIGHTS_TABLE) renames DATE_UNDERLYING.FLIGHTS;
  1993.   procedure CITIES (X : in out CITIES_TABLE)  renames DATE_UNDERLYING.CITIES;
  1994.   procedure PARCELS(X : in out PARCELS_TABLE) renames DATE_UNDERLYING.PARCELS;
  1995.   procedure OWNERS (X : in out OWNERS_TABLE)  renames DATE_UNDERLYING.OWNERS;
  1996.   procedure PARCEL_ACCOUNTS(X : in out PARCEL_ACCOUNTS_TABLE) renames
  1997.     DATE_UNDERLYING.PARCEL_ACCOUNTS;
  1998.   procedure SPECIAL_ASSESSMENTS(X : in out SPECIAL_ASSESSMENTS_TABLE) renames
  1999.     DATE_UNDERLYING.SPECIAL_ASSESSMENTS;
  2000.   procedure GENERAL_LEDGER(X : in out GENERAL_LEDGER_TABLE) renames
  2001.     DATE_UNDERLYING.GENERAL_LEDGER;
  2002.   procedure REDWOOD_LEDGER(X : in out REDWOOD_LEDGER_TABLE) renames
  2003.     DATE_UNDERLYING.REDWOOD_LEDGER;
  2004.   procedure CREEK_LEDGER(X : in out CREEK_LEDGER_TABLE) renames
  2005.     DATE_UNDERLYING.CREEK_LEDGER;
  2006.   procedure MILL_LEDGER(X : in out MILL_LEDGER_TABLE) renames
  2007.     DATE_UNDERLYING.MILL_LEDGER;
  2008.   procedure LAST_ENTRIES(X : in out LAST_ENTRIES_TABLE) renames
  2009.     DATE_UNDERLYING.LAST_ENTRIES;
  2010.  
  2011.   function CELLAR             (X : CELLAR_TABLE)              return TABLE;
  2012.   function FLIGHTS            (X : FLIGHTS_TABLE)             return TABLE;
  2013.   function CITIES             (X : CITIES_TABLE)              return TABLE;
  2014.   function PARCELS            (X : PARCELS_TABLE)             return TABLE;
  2015.   function OWNERS             (X : OWNERS_TABLE)              return TABLE;
  2016.   function PARCEL_ACCOUNTS    (X : PARCEL_ACCOUNTS_TABLE)     return TABLE;
  2017.   function SPECIAL_ASSESSMENTS(X : SPECIAL_ASSESSMENTS_TABLE) return TABLE;
  2018.   function GENERAL_LEDGER     (X : GENERAL_LEDGER_TABLE)      return TABLE;
  2019.   function REDWOOD_LEDGER     (X : REDWOOD_LEDGER_TABLE)      return TABLE;
  2020.   function CREEK_LEDGER       (X : CREEK_LEDGER_TABLE)        return TABLE;
  2021.   function MILL_LEDGER        (X : MILL_LEDGER_TABLE)         return TABLE;
  2022.   function LAST_ENTRIES       (X : LAST_ENTRIES_TABLE)        return TABLE;
  2023.  
  2024. end DATE_DATABASE;
  2025.  
  2026. with SQL_DEFINITIONS, DATE_UNDERLYING;
  2027.   use SQL_DEFINITIONS, DATE_UNDERLYING;
  2028.  
  2029. package body DATE_DATABASE is
  2030.  
  2031.   function CELLAR(X : in CELLAR_TABLE) return TABLE is
  2032.   begin
  2033.     return TABLEIFY(X.STAR);
  2034.   end CELLAR;
  2035.  
  2036.   function FLIGHTS(X : in FLIGHTS_TABLE) return TABLE is
  2037.   begin
  2038.     return TABLEIFY(X.STAR);
  2039.   end FLIGHTS;
  2040.  
  2041.   function CITIES(X : in CITIES_TABLE) return TABLE is
  2042.   begin
  2043.     return TABLEIFY(X.STAR);
  2044.   end CITIES;
  2045.  
  2046.   function PARCELS(X : in PARCELS_TABLE) return TABLE is
  2047.   begin
  2048.     return TABLEIFY(X.STAR);
  2049.   end PARCELS;
  2050.  
  2051.   function OWNERS(X : in OWNERS_TABLE) return TABLE is
  2052.   begin
  2053.     return TABLEIFY(X.STAR);
  2054.   end OWNERS;
  2055.  
  2056.   function PARCEL_ACCOUNTS(X : in PARCEL_ACCOUNTS_TABLE) return TABLE is
  2057.   begin
  2058.     return TABLEIFY(X.STAR);
  2059.   end PARCEL_ACCOUNTS;
  2060.  
  2061.   function SPECIAL_ASSESSMENTS(X : in SPECIAL_ASSESSMENTS_TABLE) return TABLE
  2062.     is
  2063.   begin
  2064.     return TABLEIFY(X.STAR);
  2065.   end SPECIAL_ASSESSMENTS;
  2066.  
  2067.   function GENERAL_LEDGER(X : in GENERAL_LEDGER_TABLE) return TABLE is
  2068.   begin
  2069.     return TABLEIFY(X.STAR);
  2070.   end GENERAL_LEDGER;
  2071.  
  2072.   function REDWOOD_LEDGER(X : in REDWOOD_LEDGER_TABLE) return TABLE is
  2073.   begin
  2074.     return TABLEIFY(X.STAR);
  2075.   end REDWOOD_LEDGER;
  2076.  
  2077.   function CREEK_LEDGER(X : in CREEK_LEDGER_TABLE) return TABLE is
  2078.   begin
  2079.     return TABLEIFY(X.STAR);
  2080.   end CREEK_LEDGER;
  2081.  
  2082.   function MILL_LEDGER(X : in MILL_LEDGER_TABLE) return TABLE is
  2083.   begin
  2084.     return TABLEIFY(X.STAR);
  2085.   end MILL_LEDGER;
  2086.  
  2087.   function LAST_ENTRIES(X : in LAST_ENTRIES_TABLE) return TABLE is
  2088.   begin
  2089.     return TABLEIFY(X.STAR);
  2090.   end LAST_ENTRIES;
  2091.  
  2092. end DATE_DATABASE;
  2093. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2094. --pgmfunc.ada
  2095. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2096. separate(SQL_DEFINITIONS.SQL_FUNCTIONS)
  2097. package body PROGRAM_FUNCTIONS is
  2098.  
  2099.   DATABASE : DATABASE_TYPE;
  2100.  
  2101.   MATCHING_TYPES : constant array(DATABASE_FIELD_TYPE) of FIELD_TYPE_TYPE :=
  2102.     ( INTEGER_FIELD => INTEGER_LITERAL,
  2103.       FLOAT_FIELD   => FLOAT_LITERAL,
  2104.       STRING_FIELD  => STRING_LITERAL);
  2105.  
  2106.   function EQUAL(LEFT, RIGHT : VALUE_LINK) return BOOLEAN is
  2107.   begin
  2108.     case LEFT.FIELD_TYPE is
  2109.       when STRING_FIELD =>
  2110.         return LEFT.STRING_VALUE.all = RIGHT.STRING_VALUE.all;
  2111.       when others =>
  2112.         return LEFT.all = RIGHT.all;
  2113.     end case;
  2114.   exception
  2115.     when CONSTRAINT_ERROR =>
  2116.       return FALSE;
  2117.   end EQUAL;
  2118.  
  2119.   function FIND_TABLE(TABLE : TABLE_NAME)
  2120.       return TABLE_LINK is
  2121.   begin
  2122.     for I in 1..DATABASE'LAST loop
  2123.       if TABLE.all = DATABASE(I).NAME.all then
  2124.         return DATABASE(I);
  2125.       end if;
  2126.     end loop;
  2127.     raise TABLE_ERROR;
  2128.   end FIND_TABLE;
  2129.  
  2130.   function FIND_FIELD(TABLE : TABLE_LINK; FIELD : FIELD_NAME)
  2131.       return FIELD_INDEX is
  2132.   begin
  2133.     for I in 1..TABLE.FIELDS'LAST loop
  2134.       if FIELD.all = TABLE.FIELDS(I).NAME.all then
  2135.         return I;
  2136.       end if;
  2137.     end loop;
  2138.     raise FIELD_ERROR;
  2139.   end FIND_FIELD;
  2140.  
  2141.   function CREATE_LITERAL_VALUE(VALUE : FIELD) return VALUE_LINK is
  2142.   begin
  2143.     case VALUE.FIELD_TYPE is
  2144.       when INTEGER_LITERAL =>
  2145.         return new VALUE_TYPE'(INTEGER_FIELD,VALUE.INTEGER_VALUE);
  2146.       when FLOAT_LITERAL =>
  2147.         return new VALUE_TYPE'(FLOAT_FIELD,VALUE.FLOAT_VALUE);
  2148.       when STRING_LITERAL =>
  2149.         return new VALUE_TYPE'(STRING_FIELD,VALUE.STRING_VALUE);
  2150.       when others =>
  2151.         raise UNIMPLEMENTED_ERROR;
  2152.     end case;
  2153.   end CREATE_LITERAL_VALUE;
  2154.  
  2155.   procedure BUILD_WHERE(CURSOR   : in out CURSOR_TYPE;
  2156.                         WHERE    : in FIELD;
  2157.                         FROM     : in TABLE_LINK) is
  2158.     FIELD_NUMBER : FIELD_INDEX;
  2159.     TARGET_TYPE  : DATABASE_FIELD_TYPE;
  2160.     LEFT,
  2161.     RIGHT        : FIELD;
  2162.   begin
  2163.     case WHERE.FIELD_TYPE is
  2164.       when EMPTY =>
  2165.         return;
  2166.       when OPERATOR =>
  2167.         null;
  2168.       when others =>
  2169.         raise SYNTAX_ERROR;
  2170.     end case;
  2171.     LEFT := WHERE.DOWN_LINK;
  2172.     RIGHT := LEFT.ACROSS_LINK;
  2173.     case WHERE.OPCODE is
  2174.       when O_AND =>
  2175.         BUILD_WHERE(CURSOR,RIGHT,FROM);
  2176.         BUILD_WHERE(CURSOR,LEFT,FROM);
  2177.       when O_EQ =>
  2178.         case LEFT.FIELD_TYPE is
  2179.           when QUALIFIED_FIELD =>
  2180.             if LEFT.RELATION.all /= FROM.NAME.all then
  2181.               raise FIELD_ERROR;
  2182.             end if;
  2183.           when UNQUALIFIED_FIELD =>
  2184.             null;
  2185.           when others =>
  2186.             raise UNIMPLEMENTED_ERROR;
  2187.         end case;
  2188.         FIELD_NUMBER := FIND_FIELD(FROM,LEFT.NAME);
  2189.         TARGET_TYPE := FROM.FIELDS(FIELD_NUMBER).DATA_TYPE;
  2190.         if RIGHT.FIELD_TYPE /=
  2191.             MATCHING_TYPES(TARGET_TYPE) then
  2192.           raise UNIMPLEMENTED_ERROR;
  2193.         end if;
  2194.         CURSOR.QUERY := new QUERY_NODE_REC'(CURSOR.QUERY,FIELD_NUMBER,
  2195.             CREATE_LITERAL_VALUE(RIGHT));
  2196.       when others =>
  2197.         raise UNIMPLEMENTED_ERROR;
  2198.     end case;
  2199.   end BUILD_WHERE;
  2200.  
  2201.   function EXECUTE(F : FIELD) return CURSOR_TYPE is
  2202.     WHAT,
  2203.     FROM_FIELD,
  2204.     WHERE,
  2205.     CLAUSE    : FIELD;
  2206.     FROM      : TABLE;
  2207.     TABLE_PTR : TABLE_LINK;
  2208.     CURSOR    : CURSOR_TYPE;
  2209.   begin
  2210.     WHAT := F.DOWN_LINK;
  2211.     FROM_FIELD := WHAT.ACROSS_LINK;
  2212.     FROM := FROM_FIELD.TABLE_LINK;
  2213.     WHERE := FROM_FIELD.ACROSS_LINK;
  2214.     CLAUSE := WHERE;
  2215.     if DATABASE = null or else F.OPCODE /= O_SELECT then
  2216.       raise CALL_ERROR;
  2217.     elsif FROM.NEXT_LINK /= null or else WHAT.NAME.all /= "*" then
  2218.       raise UNIMPLEMENTED_ERROR;
  2219.     elsif WHAT.RELATION /= null and then WHAT.RELATION.all /= FROM.NAME.all
  2220.         then
  2221.       raise FIELD_ERROR;
  2222.     end if;
  2223.     for I in 1..3 loop
  2224.       CLAUSE := CLAUSE.ACROSS_LINK;
  2225.       if CLAUSE.FIELD_TYPE /= EMPTY then
  2226.         raise UNIMPLEMENTED_ERROR;
  2227.       end if;
  2228.     end loop;
  2229.     TABLE_PTR := FIND_TABLE(FROM.NAME);
  2230.     CURSOR.CURRENT_RECORD := TABLE_PTR.RECORDS;
  2231.     BUILD_WHERE(CURSOR,WHERE,TABLE_PTR);
  2232.     return CURSOR;
  2233.   exception
  2234.     when CONSTRAINT_ERROR =>
  2235.       raise UNIMPLEMENTED_ERROR;
  2236.   end EXECUTE;
  2237.  
  2238.   procedure SET_DATABASE(DB : in DATABASE_TYPE) is
  2239.   begin
  2240.     DATABASE := DB;
  2241.   end SET_DATABASE;
  2242.  
  2243.   function EQUAL_RECORD(CURSOR : in CURSOR_TYPE) return BOOLEAN is
  2244.     COMPARE : QUERY_NODE := CURSOR.QUERY;
  2245.   begin
  2246.     while COMPARE /= null loop
  2247.       if not EQUAL(COMPARE.VALUE,CURSOR.CURRENT_RECORD.VALUES(COMPARE.FIELD))
  2248.           then
  2249.         return FALSE;
  2250.       end if;
  2251.       COMPARE := COMPARE.NEXT_NODE;
  2252.     end loop;
  2253.     return TRUE;
  2254.   end EQUAL_RECORD;
  2255.  
  2256.   procedure NEXT_RECORD(CURSOR : in out CURSOR_TYPE) is
  2257.   begin
  2258.     if CURSOR.CURRENT_RECORD = null then
  2259.       raise DONE_ERROR;
  2260.     elsif CURSOR.NEW_QUERY = TRUE then
  2261.       CURSOR.NEW_QUERY := FALSE;
  2262.     else
  2263.       CURSOR.CURRENT_RECORD := CURSOR.CURRENT_RECORD.NEXT_RECORD;
  2264.     end if;
  2265.     while CURSOR.CURRENT_RECORD /= null loop
  2266.       if EQUAL_RECORD(CURSOR) then
  2267.         return;
  2268.       end if;
  2269.       CURSOR.CURRENT_RECORD := CURSOR.CURRENT_RECORD.NEXT_RECORD;
  2270.     end loop;
  2271.     raise DONE_ERROR;
  2272.   end NEXT_RECORD;
  2273.  
  2274.   procedure FETCH_RAZOR(CURSOR : in CURSOR_TYPE; FIELD : in FIELD_INDEX) is
  2275.   begin
  2276.     if CURSOR.CURRENT_RECORD = null then
  2277.       raise CALL_ERROR;
  2278.     elsif FIELD > CURSOR.CURRENT_RECORD.VALUES'LAST then
  2279.       raise FIELD_ERROR;
  2280.     end if;
  2281.   end FETCH_RAZOR;
  2282.  
  2283.   function FETCH(CURSOR : in  CURSOR_TYPE;
  2284.                   FIELD  : in  FIELD_INDEX) return INTEGER is
  2285.   begin
  2286.     FETCH_RAZOR(CURSOR,FIELD);
  2287.     return CURSOR.CURRENT_RECORD.VALUES(FIELD).INTEGER_VALUE;
  2288.   exception
  2289.     when CONSTRAINT_ERROR =>
  2290.       raise TYPE_ERROR;
  2291.   end FETCH;
  2292.  
  2293.   function FETCH(CURSOR : in  CURSOR_TYPE;
  2294.                   FIELD  : in  FIELD_INDEX) return FLOAT is
  2295.   begin
  2296.     FETCH_RAZOR(CURSOR,FIELD);
  2297.     return CURSOR.CURRENT_RECORD.VALUES(FIELD).FLOAT_VALUE;
  2298.   exception
  2299.     when CONSTRAINT_ERROR =>
  2300.       raise TYPE_ERROR;
  2301.   end FETCH;
  2302.  
  2303.   function FETCH(CURSOR : in  CURSOR_TYPE;
  2304.                   FIELD  : in  FIELD_INDEX) return STRING is
  2305.   begin
  2306.     FETCH_RAZOR(CURSOR,FIELD);
  2307.     return CURSOR.CURRENT_RECORD.VALUES(FIELD).STRING_VALUE.all;
  2308.   exception
  2309.     when CONSTRAINT_ERROR =>
  2310.       raise TYPE_ERROR;
  2311.   end FETCH;
  2312.  
  2313.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  2314.                   FIELD  : in  FIELD_INDEX;
  2315.                   INT    : out INTEGER) is
  2316.   begin
  2317.     INT := FETCH(CURSOR,FIELD);
  2318.   end FETCH;
  2319.  
  2320.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  2321.                   FIELD  : in  FIELD_INDEX;
  2322.                   FLT    : out FLOAT) is
  2323.   begin
  2324.     FLT := FETCH(CURSOR,FIELD);
  2325.   end FETCH;
  2326.  
  2327.   procedure FETCH(CURSOR : in  CURSOR_TYPE;
  2328.                   FIELD  : in  FIELD_INDEX;
  2329.                   STR    : out STRING;
  2330.                   LAST   : out NATURAL) is
  2331.     S : STRING_LINK;
  2332.     L : NATURAL;
  2333.   begin
  2334.     FETCH_RAZOR(CURSOR,FIELD);
  2335.     S := CURSOR.CURRENT_RECORD.VALUES(FIELD).STRING_VALUE;
  2336.     if S'LENGTH > STR'LENGTH then
  2337.       raise TRUNCATE_ERROR;
  2338.     end if;
  2339.     L := STR'FIRST + S'LENGTH - 1;
  2340.     STR(STR'FIRST..L) := S.all;
  2341.     LAST := L;
  2342.   exception
  2343.     when CONSTRAINT_ERROR =>
  2344.       raise TYPE_ERROR;
  2345.   end FETCH;
  2346.  
  2347.   procedure MAKE_NEW_RECORD(TABLE : in out TABLE_LINK;
  2348.                             REC   : out RECORD_LINK) is
  2349.     NEW_RECORD : RECORD_LINK := new RECORD_TYPE(TABLE.NUMBER_FIELDS);
  2350.   begin
  2351.     for I in 1..TABLE.NUMBER_FIELDS loop
  2352.       case TABLE.FIELDS(I).DATA_TYPE is
  2353.         when INTEGER_FIELD =>
  2354.           NEW_RECORD.VALUES(I) := new VALUE_TYPE'(INTEGER_FIELD,0);
  2355.         when FLOAT_FIELD =>
  2356.           NEW_RECORD.VALUES(I) := new VALUE_TYPE'(FLOAT_FIELD,0.0);
  2357.         when STRING_FIELD =>
  2358.           NEW_RECORD.VALUES(I) :=
  2359.               new VALUE_TYPE'(STRING_FIELD,new STRING'(""));
  2360.       end case;
  2361.     end loop;
  2362.     REC := NEW_RECORD;
  2363.   end MAKE_NEW_RECORD;
  2364.  
  2365.   procedure INSERT_NEW_RECORD(TABLE : in out TABLE_LINK;
  2366.                               REC   : in     RECORD_LINK) is
  2367.     LAST_RECORD : RECORD_LINK := TABLE.RECORDS;
  2368.   begin
  2369.     if LAST_RECORD = null then
  2370.       TABLE.RECORDS := REC;
  2371.     else
  2372.       while LAST_RECORD.NEXT_RECORD /= null loop -- should save last pointer **
  2373.         LAST_RECORD := LAST_RECORD.NEXT_RECORD;
  2374.       end loop;
  2375.       LAST_RECORD.NEXT_RECORD := REC;
  2376.     end if;
  2377.   end INSERT_NEW_RECORD;
  2378.  
  2379.   procedure BUILD_INSERT_LIST(TABLE       : in TABLE_LINK;
  2380.                               FIELD_LIST  : in FIELD;
  2381.                               INSERT_LIST : in out QUERY_NODE) is
  2382.   begin
  2383.     case FIELD_LIST.FIELD_TYPE is
  2384.       when OPERATOR =>
  2385.         if FIELD_LIST.OPCODE /= O_CAT then
  2386.           raise SYNTAX_ERROR;
  2387.         end if;
  2388.         BUILD_INSERT_LIST(TABLE,FIELD_LIST.DOWN_LINK.ACROSS_LINK,INSERT_LIST);
  2389.         BUILD_INSERT_LIST(TABLE,FIELD_LIST.DOWN_LINK,INSERT_LIST);
  2390.       when UNQUALIFIED_FIELD =>
  2391.         INSERT_LIST := new QUERY_NODE_REC'(INSERT_LIST,
  2392.             FIND_FIELD(TABLE,FIELD_LIST.NAME),null);
  2393.       when others =>
  2394.         raise SYNTAX_ERROR;
  2395.     end case;
  2396.   end BUILD_INSERT_LIST;
  2397.  
  2398.   procedure INSERT_VALUES(TABLE    : in TABLE_LINK;
  2399.                           REC      : in out RECORD_LINK;
  2400.                           INTO     : in out QUERY_NODE;
  2401.                           LITERALS : in FIELD) is
  2402.     FIELD_NUMBER : FIELD_INDEX;
  2403.   begin
  2404.     case LITERALS.FIELD_TYPE is
  2405.       when OPERATOR =>
  2406.         if LITERALS.OPCODE /= O_AND then
  2407.           raise SYNTAX_ERROR;
  2408.         end if;
  2409.         INSERT_VALUES(TABLE,REC,INTO,LITERALS.DOWN_LINK);
  2410.         INSERT_VALUES(TABLE,REC,INTO,LITERALS.DOWN_LINK.ACROSS_LINK);
  2411.       when INTEGER_LITERAL | FLOAT_LITERAL | STRING_LITERAL =>
  2412.         if INTO = null then
  2413.           raise SYNTAX_ERROR;
  2414.         end if;
  2415.         FIELD_NUMBER := INTO.FIELD;
  2416.         if LITERALS.FIELD_TYPE /=
  2417.             MATCHING_TYPES(TABLE.FIELDS(FIELD_NUMBER).DATA_TYPE) then
  2418.           raise UNIMPLEMENTED_ERROR;
  2419.         end if;
  2420.         REC.VALUES(FIELD_NUMBER) := CREATE_LITERAL_VALUE(LITERALS);
  2421.         INTO := INTO.NEXT_NODE;
  2422.       when others =>
  2423.         raise SYNTAX_ERROR;
  2424.       end case;
  2425.   end INSERT_VALUES;
  2426.  
  2427.   procedure ONLY_ONE_TABLE(T : in TABLE) is
  2428.   begin
  2429.     if T.NEXT_LINK /= null then
  2430.       raise SYNTAX_ERROR;
  2431.     end if;
  2432.   end ONLY_ONE_TABLE;
  2433.  
  2434.   procedure DO_INSERT(F : in FIELD) is
  2435.     FIELD_LIST  : FIELD := F.ACROSS_LINK;
  2436.     INTO_TABLE  : TABLE := FIELD_LIST.TABLE_LINK;
  2437.     TABLE_PTR   : TABLE_LINK;
  2438.     VALUE_LIST  : FIELD := F.DOWN_LINK;
  2439.     NEW_RECORD  : RECORD_LINK;
  2440.     INSERT_LIST : QUERY_NODE;
  2441.   begin
  2442.     ONLY_ONE_TABLE(INTO_TABLE);
  2443.     TABLE_PTR := FIND_TABLE(INTO_TABLE.NAME);
  2444.     FIELD_LIST := FIELD_LIST.ACROSS_LINK;
  2445.     MAKE_NEW_RECORD(TABLE_PTR,NEW_RECORD);
  2446.     if FIELD_LIST = null then
  2447.       raise UNIMPLEMENTED_ERROR;
  2448.     else
  2449.       if VALUE_LIST.FIELD_TYPE = OPERATOR and then
  2450.           VALUE_LIST.OPCODE = O_SELECT then
  2451.         raise UNIMPLEMENTED_ERROR;
  2452.       end if;
  2453.       BUILD_INSERT_LIST(TABLE_PTR,FIELD_LIST,INSERT_LIST);
  2454.       INSERT_VALUES(TABLE_PTR,NEW_RECORD,INSERT_LIST,VALUE_LIST);
  2455.       if INSERT_LIST /= null then
  2456.         raise SYNTAX_ERROR;
  2457.       end if;
  2458.       INSERT_NEW_RECORD(TABLE_PTR,NEW_RECORD);
  2459.     end if;
  2460.   end DO_INSERT;
  2461.  
  2462.   procedure DO_DELETE(F : in FIELD) is
  2463.     WHERE     : FIELD := F.DOWN_LINK;
  2464.     FROM      : TABLE := WHERE.TABLE_LINK;
  2465.     CURSOR    : CURSOR_TYPE;
  2466.     TABLE_PTR : TABLE_LINK;
  2467.     PREVIOUS  : RECORD_LINK;
  2468.   begin
  2469.     ONLY_ONE_TABLE(FROM);
  2470.     TABLE_PTR := FIND_TABLE(FROM.NAME);
  2471.     CURSOR.CURRENT_RECORD := TABLE_PTR.RECORDS;
  2472.     BUILD_WHERE(CURSOR,WHERE.ACROSS_LINK,TABLE_PTR);
  2473.     while CURSOR.CURRENT_RECORD /= null and then EQUAL_RECORD(CURSOR) loop
  2474.       CURSOR.CURRENT_RECORD := CURSOR.CURRENT_RECORD.NEXT_RECORD;
  2475.       TABLE_PTR.RECORDS := CURSOR.CURRENT_RECORD;
  2476.     end loop;
  2477.     PREVIOUS := CURSOR.CURRENT_RECORD;
  2478.     if PREVIOUS /= null then
  2479.       while PREVIOUS.NEXT_RECORD /= null loop
  2480.         CURSOR.CURRENT_RECORD := PREVIOUS.NEXT_RECORD;
  2481.         if EQUAL_RECORD(CURSOR) then
  2482.           PREVIOUS.NEXT_RECORD := CURSOR.CURRENT_RECORD.NEXT_RECORD;
  2483.         else
  2484.           PREVIOUS := CURSOR.CURRENT_RECORD;
  2485.         end if;
  2486.       end loop;
  2487.     end if;
  2488.   end DO_DELETE;
  2489.  
  2490.   procedure BUILD_SET_LIST(SET_LIST : in out QUERY_NODE;
  2491.                            SET      : in FIELD;
  2492.                            WHAT     : in TABLE_LINK) is
  2493.     FIELD_NUMBER : FIELD_INDEX;
  2494.     TARGET_TYPE  : DATABASE_FIELD_TYPE;
  2495.     LEFT,
  2496.     RIGHT        : FIELD;
  2497.   begin
  2498.     if SET.FIELD_TYPE /= OPERATOR then
  2499.       raise SYNTAX_ERROR;
  2500.     end if;
  2501.     LEFT := SET.DOWN_LINK; RIGHT := LEFT.ACROSS_LINK;
  2502.     case SET.OPCODE is
  2503.       when O_CAT =>
  2504.         BUILD_SET_LIST(SET_LIST,RIGHT,WHAT);
  2505.         BUILD_SET_LIST(SET_LIST,LEFT,WHAT);
  2506.       when O_EQ =>
  2507.         if LEFT.FIELD_TYPE /= UNQUALIFIED_FIELD then
  2508.           raise SYNTAX_ERROR;
  2509.         end if;
  2510.         FIELD_NUMBER := FIND_FIELD(WHAT,LEFT.NAME);
  2511.         TARGET_TYPE := WHAT.FIELDS(FIELD_NUMBER).DATA_TYPE;
  2512.         if RIGHT.FIELD_TYPE /=
  2513.             MATCHING_TYPES(TARGET_TYPE) then
  2514.           raise UNIMPLEMENTED_ERROR;
  2515.         end if;
  2516.         SET_LIST := new QUERY_NODE_REC'(SET_LIST,FIELD_NUMBER,
  2517.           CREATE_LITERAL_VALUE(RIGHT));
  2518.       when others =>
  2519.         raise SYNTAX_ERROR;
  2520.     end case;
  2521.   end BUILD_SET_LIST;
  2522.  
  2523.   procedure DO_UPDATE(F : in FIELD) is
  2524.     FROM      : TABLE := F.DOWN_LINK.TABLE_LINK;
  2525.     SET       : FIELD := F.DOWN_LINK.ACROSS_LINK;
  2526.     WHERE     : FIELD := SET.ACROSS_LINK;
  2527.     TABLE_PTR : TABLE_LINK;
  2528.     SET_LIST,
  2529.     SET_NOW   : QUERY_NODE;
  2530.     CURSOR    : CURSOR_TYPE;
  2531.   begin
  2532.     ONLY_ONE_TABLE(FROM);
  2533.     TABLE_PTR := FIND_TABLE(FROM.NAME);
  2534.     CURSOR.CURRENT_RECORD := TABLE_PTR.RECORDS;
  2535.     BUILD_WHERE(CURSOR,WHERE,TABLE_PTR);
  2536.     BUILD_SET_LIST(SET_LIST,SET,TABLE_PTR);
  2537.     loop
  2538.       NEXT_RECORD(CURSOR);
  2539.       SET_NOW := SET_LIST;
  2540.       while SET_NOW /= null loop
  2541.         CURSOR.CURRENT_RECORD.VALUES(SET_NOW.FIELD) := SET_NOW.VALUE;
  2542.         SET_NOW := SET_NOW.NEXT_NODE;
  2543.       end loop;
  2544.     end loop;
  2545.   exception
  2546.     when DONE_ERROR =>
  2547.       return;
  2548.   end DO_UPDATE;
  2549.  
  2550.   procedure EXECUTE(F : in FIELD) is
  2551.   begin
  2552.     case F.OPCODE is
  2553.       when O_INSERT =>
  2554.         DO_INSERT(F);
  2555.       when O_DELETE =>
  2556.         DO_DELETE(F);
  2557.       when O_UPDATE =>
  2558.         DO_UPDATE(F);
  2559.       when others =>
  2560.         raise SYNTAX_ERROR;
  2561.     end case;
  2562.   exception
  2563.     when CONSTRAINT_ERROR =>
  2564.       raise SYNTAX_ERROR;
  2565.   end EXECUTE;
  2566.  
  2567.   procedure LIST(F : in FIELD) is
  2568.   begin
  2569.     null;
  2570.   end LIST;
  2571.  
  2572. end PROGRAM_FUNCTIONS;
  2573. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2574. --bulkfunc.ada
  2575. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2576. with TEXT_INPUT, TEXT_IO, TEXT_PRINT;
  2577.   use TEXT_INPUT, TEXT_IO, TEXT_PRINT;
  2578.  
  2579. separate(SQL_DEFINITIONS.SQL_FUNCTIONS)
  2580. package body BULK_FUNCTIONS is
  2581.  
  2582.   type TABLE_LIST_REC;
  2583.  
  2584.   type TABLE_LIST_LINK is access TABLE_LIST_REC;
  2585.  
  2586.   type TABLE_LIST_REC is
  2587.     record
  2588.       NEXT_TABLE : TABLE_LIST_LINK;
  2589.       TABLE      : TABLE_LINK;
  2590.     end record;
  2591.  
  2592.   type FIELD_LINK is access FIELD_TYPE;
  2593.  
  2594.   type FIELD_LIST_REC;
  2595.  
  2596.   type FIELD_LIST_LINK is access FIELD_LIST_REC;
  2597.  
  2598.   type FIELD_LIST_REC is
  2599.     record
  2600.       NEXT_FIELD : FIELD_LIST_LINK;
  2601.       FIELD      : FIELD_LINK;
  2602.     end record;
  2603.  
  2604.   function CHECK_FIELD_LIST(BUFFER     : BUFFER_TYPE;
  2605.                             FIELD_LIST : FIELD_LIST_LINK; -- return -> last one
  2606.                             NAME       : FIELD_NAME) return FIELD_LIST_LINK is
  2607.     FIELD : FIELD_LIST_LINK := FIELD_LIST;
  2608.   begin
  2609.     loop
  2610.       if NAME.all = FIELD.FIELD.NAME.all then
  2611.         CARD_ERROR(BUFFER,"DBLOAD - Duplicate FIELD name");
  2612.       end if;
  2613.       exit when FIELD.NEXT_FIELD = null;
  2614.       FIELD := FIELD.NEXT_FIELD;
  2615.     end loop;
  2616.     return FIELD;
  2617.   end CHECK_FIELD_LIST;
  2618.  
  2619.   function CHECK_TABLE_LIST(BUFFER     : BUFFER_TYPE;
  2620.                             TABLE_LIST : TABLE_LIST_LINK; -- return -> last one
  2621.                             NAME       : TABLE_NAME) return TABLE_LIST_LINK is
  2622.     TABLE : TABLE_LIST_LINK := TABLE_LIST;
  2623.   begin
  2624.     loop
  2625.       if NAME.all = TABLE.TABLE.NAME.all then
  2626.         CARD_ERROR(BUFFER,"DBLOAD - Duplicate TABLE name");
  2627.       end if;
  2628.       exit when TABLE.NEXT_TABLE = null;
  2629.       TABLE := TABLE.NEXT_TABLE;
  2630.     end loop;
  2631.     return TABLE;
  2632.   end CHECK_TABLE_LIST;
  2633.  
  2634.   function COMBINE_FIELDS(TABLE       : TABLE_NAME;
  2635.                           FIRST_FIELD : FIELD_LIST_LINK) return TABLE_LINK is
  2636.     F : FIELD_LIST_LINK := FIRST_FIELD;
  2637.     T : TABLE_LINK;
  2638.     C : EXTENDED_FIELD_INDEX := 0;
  2639.   begin
  2640.     while F /= null loop
  2641.       C := C + 1;
  2642.       F := F.NEXT_FIELD;
  2643.     end loop;
  2644.     T := new TABLE_TYPE(C);
  2645.     T.NAME := TABLE;
  2646.     F := FIRST_FIELD;
  2647.     for I in 1..C loop
  2648.       T.FIELDS(I) := F.FIELD.all;
  2649.       F := F.NEXT_FIELD;
  2650.     end loop;
  2651.     return T;
  2652.   end COMBINE_FIELDS;
  2653.  
  2654.   function COMBINE_TABLES(FIRST_TABLE : TABLE_LIST_LINK) return DATABASE_TYPE
  2655.       is
  2656.     D : DATABASE_TYPE;
  2657.     T : TABLE_LIST_LINK := FIRST_TABLE;
  2658.     C : EXTENDED_TABLE_INDEX := 0;
  2659.   begin
  2660.     while T /= null loop
  2661.       C := C + 1;
  2662.       T := T.NEXT_TABLE;
  2663.     end loop;
  2664.     D := new TABLE_ARRAY(1..C);
  2665.     T := FIRST_TABLE;
  2666.     for I in 1..C loop
  2667.       D(I) := T.TABLE;
  2668.       T := T.NEXT_TABLE;
  2669.     end loop;
  2670.     return D;
  2671.   end COMBINE_TABLES;
  2672.  
  2673.   procedure GET_DATA(BUFFER : in out BUFFER_TYPE;
  2674.                      IDENT  : in out STRING;
  2675.                      LAST   : in out POSITIVE;
  2676.                      TABLE  : in out TABLE_LINK) is
  2677.     LAST_RECORD  : RECORD_LINK := new RECORD_TYPE(0);
  2678.   begin
  2679.     TABLE.RECORDS := LAST_RECORD;
  2680.     loop
  2681.       exit when IDENT(1..LAST) /= "DATA";
  2682.       LAST_RECORD.NEXT_RECORD := new RECORD_TYPE(TABLE.NUMBER_FIELDS);
  2683.       LAST_RECORD := LAST_RECORD.NEXT_RECORD;
  2684.       begin
  2685.         for I in 1..TABLE.NUMBER_FIELDS loop
  2686.           case TABLE.FIELDS(I).DATA_TYPE is
  2687.             when INTEGER_FIELD =>
  2688.               LAST_RECORD.VALUES(I) :=
  2689.                 new VALUE_TYPE'(INTEGER_FIELD,IN_INTEGER(BUFFER));
  2690.             when FLOAT_FIELD =>
  2691.               LAST_RECORD.VALUES(I) :=
  2692.                 new VALUE_TYPE'(FLOAT_FIELD,IN_FLOAT(BUFFER));
  2693.             when STRING_FIELD =>
  2694.               LAST_RECORD.VALUES(I) :=
  2695.                 new VALUE_TYPE'(STRING_FIELD,IN_STRING(BUFFER));
  2696.               if LAST_RECORD.VALUES(I).STRING_VALUE'LENGTH >
  2697.                   TABLE.FIELDS(I).SIZE then
  2698.                 CARD_ERROR(BUFFER,"DBLOAD - STRING longer than declaration");
  2699.               end if;
  2700.           end case;
  2701.         end loop;
  2702.       exception
  2703.         when END_ERROR =>
  2704.           CARD_ERROR(BUFFER,"DBLOAD - end of file before all DATA read");
  2705.         when others =>
  2706.           CARD_ERROR(BUFFER,"DBLOAD - improper format on data");
  2707.       end;
  2708.       IN_IDENT(BUFFER,IDENT,LAST);
  2709.     end loop;
  2710.     TABLE.RECORDS := TABLE.RECORDS.NEXT_RECORD;
  2711.   exception
  2712.     when END_ERROR =>
  2713.       TABLE.RECORDS := TABLE.RECORDS.NEXT_RECORD;
  2714.   end GET_DATA;
  2715.  
  2716.   procedure GET_FIELDS(BUFFER : in out BUFFER_TYPE;
  2717.                        IDENT  : in out STRING;
  2718.                        LAST   : in out POSITIVE;
  2719.                        FIELD1 : out    FIELD_LIST_LINK) is
  2720.     FIELD_LIST : FIELD_LIST_LINK := new FIELD_LIST_REC'(null,
  2721.         new FIELD_TYPE'(new FIELD_NAME_STRING'(""),STRING_FIELD,1));
  2722.     LAST_FIELD : FIELD_LIST_LINK;
  2723.     FLD_NAME   : FIELD_NAME;
  2724.     TYPE_FIELD : DATABASE_FIELD_TYPE;
  2725.   begin
  2726.     loop
  2727.       exit when IDENT(1..LAST) /= "FIELD";
  2728.       begin
  2729.         IN_IDENT(BUFFER,IDENT,LAST);
  2730.         FLD_NAME := new FIELD_NAME_STRING'(FIELD_NAME_STRING(IDENT(1..LAST)));
  2731.         LAST_FIELD := CHECK_FIELD_LIST(BUFFER,FIELD_LIST,FLD_NAME);
  2732.         IN_IDENT(BUFFER,IDENT,LAST);
  2733.         TYPE_FIELD := DATABASE_FIELD_TYPE'VALUE(IDENT(1..LAST) & "_FIELD");
  2734.         LAST_FIELD.NEXT_FIELD := new FIELD_LIST_REC'(null,
  2735.             new FIELD_TYPE'(FLD_NAME,TYPE_FIELD,1));
  2736.         LAST_FIELD.NEXT_FIELD.FIELD.SIZE := IN_INTEGER(BUFFER);
  2737.       exception
  2738.         when END_ERROR =>
  2739.           CARD_ERROR(BUFFER,
  2740.               "DBLOAD - premature end of file in FIELD description");
  2741.         when others =>
  2742.           CARD_ERROR(BUFFER,"DBLOAD - invalid field description");
  2743.       end;
  2744.       IN_IDENT(BUFFER,IDENT,LAST);
  2745.     end loop;
  2746.     FIELD1 := FIELD_LIST.NEXT_FIELD;
  2747.   exception
  2748.     when END_ERROR =>
  2749.       FIELD1 := FIELD_LIST.NEXT_FIELD;
  2750.   end GET_FIELDS;
  2751.  
  2752.   function LOAD_DATABASE(FILE_NAME : in STRING) return DATABASE_TYPE is
  2753.     BUFFER     : BUFFER_TYPE := MAKE_BUFFER(100);
  2754.     IDENT      : STRING(1..100);
  2755.     LAST       : NATURAL;
  2756.     TABLE_LIST : TABLE_LIST_LINK := new TABLE_LIST_REC'(null,
  2757.         new TABLE_TYPE'(0,new TABLE_NAME_STRING'(""),null,
  2758.         (1..0 => FIELD_TYPE'(new FIELD_NAME_STRING'(""),STRING_FIELD,1))));
  2759.     FIELD_LIST : FIELD_LIST_LINK;
  2760.     LAST_TABLE : TABLE_LIST_LINK;
  2761.     TBL_NAME   : TABLE_NAME;
  2762.   begin
  2763.     OPEN_INPUT(BUFFER,IN_FILE,FILE_NAME);
  2764.     IN_IDENT(BUFFER,IDENT,LAST);
  2765.     while not END_OF_FILE(BUFFER) loop
  2766.       exit when IDENT(1..LAST) = "END"; -- exceptions are not propagating right
  2767.       if IDENT(1..LAST) /= "TABLE" then
  2768.         CARD_ERROR(BUFFER,"DBLOAD - TABLE card expected, not found");
  2769.       end if;
  2770.       begin
  2771.         IN_IDENT(BUFFER,IDENT,LAST);
  2772.       exception
  2773.         when others =>
  2774.           CARD_ERROR(BUFFER,"DBLOAD - invalid TABLE card");
  2775.       end;
  2776.       TBL_NAME := new TABLE_NAME_STRING'(TABLE_NAME_STRING(IDENT(1..LAST)));
  2777.       LAST_TABLE := CHECK_TABLE_LIST(BUFFER,TABLE_LIST,TBL_NAME);
  2778.       IN_IDENT(BUFFER,IDENT,LAST);
  2779.       GET_FIELDS(BUFFER,IDENT,LAST,FIELD_LIST);
  2780.       LAST_TABLE.NEXT_TABLE := new TABLE_LIST_REC'(null,
  2781.         COMBINE_FIELDS(TBL_NAME,FIELD_LIST));
  2782.       GET_DATA(BUFFER,IDENT,LAST,LAST_TABLE.NEXT_TABLE.TABLE);
  2783.     end loop;
  2784.     CLOSE_INPUT(BUFFER);
  2785.     return COMBINE_TABLES(TABLE_LIST.NEXT_TABLE);
  2786.   end LOAD_DATABASE;
  2787.  
  2788.   procedure SAVE_DATA(FILE  : in FILE_TYPE;
  2789.                       TABLE : in TABLE_LINK;
  2790.                       REC   : in RECORD_LINK) is
  2791.   begin
  2792.     PRINT(FILE,"DATA");
  2793.     for I in 1..TABLE.NUMBER_FIELDS loop
  2794.       PRINT(FILE," ");
  2795.       case TABLE.FIELDS(I).DATA_TYPE is
  2796.         when INTEGER_FIELD =>
  2797.           PRINT(FILE,REC.VALUES(I).INTEGER_VALUE,NO_BREAK);
  2798.         when FLOAT_FIELD =>
  2799.           PRINT(FILE,REC.VALUES(I).FLOAT_VALUE,NO_BREAK);
  2800.         when STRING_FIELD =>
  2801.           PRINT(FILE,"""" & REC.VALUES(I).STRING_VALUE.all & """",NO_BREAK);
  2802.       end case;
  2803.     end loop;
  2804.     PRINT_LINE(FILE);
  2805.   end SAVE_DATA;
  2806.  
  2807.   procedure SAVE_FIELDS(FILE : in FILE_TYPE; TABLE : in TABLE_LINK) is
  2808.     FIELD : FIELD_TYPE;
  2809.   begin
  2810.     for I in 1..TABLE.NUMBER_FIELDS loop
  2811.       FIELD := TABLE.FIELDS(I);
  2812.       PRINT(FILE,"FIELD " & STRING(FIELD.NAME.all) & " ");
  2813.       case FIELD.DATA_TYPE is
  2814.         when INTEGER_FIELD =>
  2815.           PRINT(FILE,"INTEGER ",NO_BREAK);
  2816.         when FLOAT_FIELD =>
  2817.           PRINT(FILE,"FLOAT ",NO_BREAK);
  2818.         when STRING_FIELD =>
  2819.           PRINT(FILE,"STRING ",NO_BREAK);
  2820.       end case;
  2821.       PRINT(FILE,FIELD.SIZE); PRINT_LINE(FILE);
  2822.     end loop;
  2823.   end SAVE_FIELDS;
  2824.  
  2825.   procedure SAVE_DATABASE(FILE_NAME : in STRING; DATABASE : in DATABASE_TYPE)
  2826.       is
  2827.     FILE  : FILE_TYPE;
  2828.     L     : LINE_TYPE;
  2829.     TABLE : TABLE_LINK;
  2830.     REC   : RECORD_LINK;
  2831.   begin
  2832.     CREATE(FILE,OUT_FILE,FILE_NAME); CREATE_LINE(L,79); SET_LINE(L);
  2833.     for I in 1..DATABASE'LAST loop
  2834.       BLANK_LINE(FILE);
  2835.       TABLE := DATABASE(I);
  2836.       PRINT(FILE,"TABLE " & STRING(TABLE.NAME.all));
  2837.       PRINT_LINE(FILE); BLANK_LINE(FILE);
  2838.       SAVE_FIELDS(FILE,TABLE);
  2839.       REC := TABLE.RECORDS;
  2840.       if REC /= null then
  2841.         BLANK_LINE(FILE);
  2842.         while REC /= null loop
  2843.           SAVE_DATA(FILE,TABLE,REC);
  2844.           REC := REC.NEXT_RECORD;
  2845.         end loop;
  2846.       end if;
  2847.     end loop;
  2848.     BLANK_LINE(FILE); PRINT(FILE,"END"); PRINT_LINE(FILE);
  2849.     PRINT(FILE,"END"); PRINT_LINE(FILE);
  2850.     CLOSE(FILE);
  2851.   end SAVE_DATABASE;
  2852.  
  2853. end BULK_FUNCTIONS;
  2854. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2855. --show.ada
  2856. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2857. with TEXT_PRINT;
  2858.   use TEXT_PRINT;
  2859.  
  2860. separate(SQL_DEFINITIONS.SQL_FUNCTIONS)
  2861. package body SHOW_PACKAGE is
  2862.  
  2863.   type TABLE_LIST_REC;
  2864.  
  2865.   type TABLE_LIST is access TABLE_LIST_REC;
  2866.  
  2867.   type TABLE_LIST_REC is
  2868.     record
  2869.       NAME,
  2870.       PRINT        : TABLE_NAME;
  2871.       VERSION_LINK,
  2872.       NAME_LINK    : TABLE_LIST;
  2873.     end record;
  2874.  
  2875.   type PRECEDENCE_TYPE is range 1..10; -- SQL, not Ada, operator precedence
  2876.  
  2877.   type CLAUSE_NAME_TYPE is new STRING(1..7);
  2878.  
  2879.   procedure SHOWR(F : in FIELD);
  2880.       
  2881.   INDENT        : INTEGER;
  2882.   TABLE_TABLE   : TABLE_LIST;
  2883.   DOING_SET     : BOOLEAN := FALSE;
  2884.   INITIAL_TABLE : constant TABLE_LIST := new TABLE_LIST_REC'(
  2885.                                   new TABLE_NAME_STRING'(""),null,null,null);
  2886.  
  2887.   PRECEDENCE : constant array(OPERATOR_TYPE) of PRECEDENCE_TYPE := (
  2888.     O_SELECT | O_INSERT | O_DELETE | O_UPDATE | O_SUM | O_AVG | O_MAX |
  2889.         O_MIN | O_COUNT | O_DESC | O_CAT                                => 10,
  2890.     O_ABS                                                               => 9,
  2891.     O_POWER                                                             => 8,
  2892.     O_TIMES | O_DIV | O_MOD | O_REM                                     => 7,
  2893.     O_UNARY_PLUS | O_UNARY_MINUS                                        => 6,
  2894.     O_PLUS | O_MINUS                                                    => 5,
  2895.     O_EQ | O_NE | O_LT | O_LE | O_GT | O_GE | O_LIKE | O_IN | O_EXISTS  => 4,
  2896.     O_NOT                                                               => 3,
  2897.     O_AND                                                               => 2,
  2898.     O_OR | O_XOR                                                        => 1);
  2899.  
  2900.   OPERATOR_NAME : constant array(OPERATOR_TYPE) of STRING_LINK := (
  2901.     new STRING'("SELECT"), new STRING'("INSERT"), new STRING'("DELETE"),
  2902.     new STRING'("UPDATE"), new STRING'("LIKE"),   new STRING'("SUM"),
  2903.     new STRING'("AVG"),    new STRING'("MAX"),    new STRING'("MIN"),
  2904.     new STRING'("COUNT"),  new STRING'("IN"),     new STRING'("EXISTS"),
  2905.     new STRING'("DESC"),   new STRING'("AND"),    new STRING'("OR"),
  2906.     new STRING'("XOR"),    new STRING'("="),      new STRING'("/="),
  2907.     new STRING'("<"),      new STRING'("<="),     new STRING'(">"),
  2908.     new STRING'(">="),     new STRING'("+"),      new STRING'("-"),
  2909.     new STRING'(","),      new STRING'("+"),      new STRING'("-"),
  2910.     new STRING'("*"),      new STRING'("/"),      new STRING'("MOD"),
  2911.     new STRING'("REM"),    new STRING'("**"),    new STRING'("ABS"),
  2912.     new STRING'("NOT") );
  2913.  
  2914.   CLAUSE_NAME : constant array(1..4) of CLAUSE_NAME_TYPE :=
  2915.     ("WHERE  ", "GROUP  ", "HAVING ", "ORDER  ");
  2916.  
  2917.   HAS_BY : constant array(1..4) of BOOLEAN := (FALSE, TRUE, FALSE, TRUE);
  2918.  
  2919.   SIX_BLANKS : constant STRING := "      ";
  2920.  
  2921.   procedure ENTER_NEW_TABLE(T : TABLE_NAME) is
  2922.     NAME_ENTRY    : TABLE_LIST := TABLE_TABLE;
  2923.     VERSION_ENTRY : TABLE_LIST;
  2924.   begin
  2925.     loop
  2926.       if NAME_ENTRY.NAME.all = T.all then
  2927.         VERSION_ENTRY := NAME_ENTRY;
  2928.         loop
  2929.           if VERSION_ENTRY.NAME = T then
  2930.             return;
  2931.           end if;
  2932.           exit when VERSION_ENTRY.VERSION_LINK = null;
  2933.           VERSION_ENTRY := VERSION_ENTRY.VERSION_LINK;
  2934.         end loop;
  2935.         VERSION_ENTRY.VERSION_LINK := new TABLE_LIST_REC'(T,T,null,null);
  2936.         return;
  2937.       end if;
  2938.       exit when NAME_ENTRY.NAME_LINK = null;
  2939.       NAME_ENTRY := NAME_ENTRY.NAME_LINK;
  2940.     end loop;
  2941.     NAME_ENTRY.NAME_LINK := new TABLE_LIST_REC'(T,T,null,null);
  2942.   end ENTER_NEW_TABLE;
  2943.  
  2944.   procedure CREATE_TABLE_TABLE(F : in FIELD) is
  2945.     G : FIELD;
  2946.     T : TABLE;
  2947.   begin
  2948.     case F.FIELD_TYPE is
  2949.       when OPERATOR =>
  2950.         G := F.DOWN_LINK;
  2951.         while G /= null loop
  2952.           CREATE_TABLE_TABLE(G);
  2953.           G := G.ACROSS_LINK;
  2954.         end loop;
  2955.       when QUALIFIED_FIELD =>
  2956.         ENTER_NEW_TABLE(F.RELATION);
  2957.       when FROM_LIST =>
  2958.         T := F.TABLE_LINK;
  2959.         while T /= null loop
  2960.           ENTER_NEW_TABLE(T.NAME);
  2961.           T := T.NEXT_LINK;
  2962.         end loop;
  2963.       when others =>
  2964.         null;
  2965.     end case;
  2966.   end CREATE_TABLE_TABLE;
  2967.  
  2968.   procedure FINALIZE_TABLE_TABLE is
  2969.     NAME_ENTRY : TABLE_LIST := TABLE_TABLE;
  2970.     VERSION_ENTRY,NEXT_NAME,NEXT_VERSION : TABLE_LIST;
  2971.     VERSION_NUMBER,NAME_LENGTH : INTEGER;
  2972.   begin
  2973.     while NAME_ENTRY /= null loop
  2974.       if NAME_ENTRY.VERSION_LINK /= null then
  2975.         VERSION_NUMBER := 1;
  2976.         VERSION_ENTRY := NAME_ENTRY;
  2977.         NAME_LENGTH := VERSION_ENTRY.NAME'LENGTH;
  2978.         while VERSION_ENTRY /= null loop
  2979.           VERSION_ENTRY.PRINT := new TABLE_NAME_STRING'(
  2980.             TABLE_NAME_STRING(
  2981.               STRING(VERSION_ENTRY.NAME.all) &
  2982.                 INTEGER'IMAGE(VERSION_NUMBER) & ")" ) );
  2983.           VERSION_ENTRY.PRINT(NAME_LENGTH+1) := '(';
  2984.           VERSION_NUMBER := VERSION_NUMBER + 1;
  2985.           NEXT_NAME := NAME_ENTRY.NAME_LINK;
  2986.           NEXT_VERSION := VERSION_ENTRY.VERSION_LINK;
  2987.           NAME_ENTRY.NAME_LINK := VERSION_ENTRY;
  2988.           VERSION_ENTRY.NAME_LINK := NEXT_NAME;
  2989.           NAME_ENTRY := VERSION_ENTRY;
  2990.           VERSION_ENTRY := NEXT_VERSION;
  2991.         end loop;
  2992.       end if;
  2993.       NAME_ENTRY := NAME_ENTRY.NAME_LINK;
  2994.     end loop;
  2995.   end FINALIZE_TABLE_TABLE;
  2996.  
  2997.   procedure SHOW_TABLE_NAME(NAME : in TABLE_NAME) is
  2998.     T : TABLE_LIST := TABLE_TABLE;
  2999.   begin
  3000.     loop
  3001.       if NAME = T.NAME then
  3002.         PRINT(STRING(T.PRINT.all),NO_BREAK);
  3003.         return;
  3004.       end if;
  3005.       T := T.NAME_LINK;
  3006.     end loop;
  3007.   end SHOW_TABLE_NAME;
  3008.  
  3009.   procedure SHOW_SELECT(F : in FIELD) is
  3010.     CLAUSE : FIELD;
  3011.     T      : TABLE;
  3012.   begin
  3013.     INDENT := INDENT + 7;
  3014.     if INDENT > 0 then
  3015.       SET_INDENT(INDENT-1); PRINT_LINE; PRINT("("); SET_INDENT(INDENT);
  3016.     else
  3017.       SET_INDENT(INDENT); PRINT_LINE;
  3018.     end if;
  3019.     PRINT("SELECT "); CLAUSE := F.DOWN_LINK; SHOWR(CLAUSE);
  3020.     CLAUSE := CLAUSE.ACROSS_LINK; T := CLAUSE.TABLE_LINK;
  3021.     if T /= null then
  3022.       PRINT_LINE; PRINT("FROM   ");
  3023.       loop
  3024.         SHOW_TABLE_NAME(T.NAME); T := T.NEXT_LINK;
  3025.         exit when T = null;
  3026.         PRINT(", ");
  3027.       end loop;
  3028.     end if;
  3029.     for I in 1..4 loop
  3030.       CLAUSE := CLAUSE.ACROSS_LINK;
  3031.       if CLAUSE.FIELD_TYPE /= EMPTY then
  3032.         PRINT_LINE; PRINT(STRING(CLAUSE_NAME(I)));
  3033.         if HAS_BY(I) then
  3034.           PRINT("BY ");
  3035.         end if;
  3036.         SHOWR(CLAUSE);
  3037.       end if;
  3038.     end loop;
  3039.     INDENT := INDENT - 7;
  3040.     if INDENT >= 0 then
  3041.       PRINT(")"); SET_INDENT(INDENT);
  3042.     end if;
  3043.   end SHOW_SELECT;
  3044.  
  3045.   procedure START_STATEMENT is
  3046.   begin
  3047.     INDENT := INDENT + 7; SET_INDENT(INDENT); PRINT_LINE;
  3048.   end START_STATEMENT;
  3049.  
  3050.   procedure SHOW_INSERT(F : in FIELD) is
  3051.     CLAUSE : FIELD;
  3052.   begin
  3053.     START_STATEMENT; PRINT("INSERT INTO ");
  3054.     CLAUSE := F.ACROSS_LINK;
  3055.     SHOW_TABLE_NAME(CLAUSE.TABLE_LINK.NAME);
  3056.     if CLAUSE.ACROSS_LINK /= null then
  3057.       PRINT(" ( "); SHOWR(CLAUSE.ACROSS_LINK); PRINT(" )");
  3058.     end if;
  3059.     CLAUSE := F.DOWN_LINK;
  3060.     if CLAUSE.FIELD_TYPE = OPERATOR and then CLAUSE.OPCODE = O_SELECT then
  3061.       SHOW_SELECT(CLAUSE);
  3062.     else
  3063.       START_STATEMENT;
  3064.       PRINT("VALUES ("); SHOWR(CLAUSE); PRINT(")");
  3065.       INDENT := INDENT - 7; SET_INDENT(INDENT);
  3066.     end if;
  3067.     INDENT := INDENT - 7;
  3068.   end SHOW_INSERT;
  3069.  
  3070.   procedure SHOW_WHERE(F : in FIELD) is
  3071.   begin
  3072.     if F.FIELD_TYPE /= EMPTY then
  3073.       PRINT_LINE; PRINT("WHERE  "); SHOWR(F);
  3074.     end if;
  3075.   end SHOW_WHERE;
  3076.  
  3077.   procedure SHOW_DELETE(F : in FIELD) is
  3078.     CLAUSE : FIELD;
  3079.   begin
  3080.     START_STATEMENT; PRINT("DELETE");
  3081.     CLAUSE := F.DOWN_LINK;
  3082.     if CLAUSE.TABLE_LINK /= null then
  3083.       PRINT_LINE; PRINT("FROM   "); SHOW_TABLE_NAME(CLAUSE.TABLE_LINK.NAME);
  3084.     end if;
  3085.     SHOW_WHERE(CLAUSE.ACROSS_LINK);
  3086.     INDENT := INDENT - 7;
  3087.   end SHOW_DELETE;
  3088.  
  3089.   procedure SHOW_UPDATE(F : in FIELD) is
  3090.     CLAUSE : FIELD;
  3091.   begin
  3092.     START_STATEMENT; PRINT("UPDATE ");
  3093.     CLAUSE := F.DOWN_LINK;
  3094.     if CLAUSE.TABLE_LINK /= null then
  3095.       SHOW_TABLE_NAME(CLAUSE.TABLE_LINK.NAME);
  3096.     end if;
  3097.     PRINT_LINE; PRINT("SET    "); INDENT := INDENT + 7; SET_INDENT(INDENT);
  3098.     CLAUSE := CLAUSE.ACROSS_LINK;
  3099.     DOING_SET := TRUE; SHOWR(CLAUSE); DOING_SET := FALSE;
  3100.     INDENT := INDENT - 7; SET_INDENT(INDENT);
  3101.     SHOW_WHERE(CLAUSE.ACROSS_LINK);
  3102.     INDENT := INDENT - 7;
  3103.   end SHOW_UPDATE;
  3104.  
  3105.   procedure SHOW_PRECEDENCE(UPPER_PRECEDENCE : in PRECEDENCE_TYPE;
  3106.                             OPERAND          : in FIELD) is
  3107.   begin
  3108.     if OPERAND.FIELD_TYPE = OPERATOR and then
  3109.         PRECEDENCE(OPERAND.OPCODE) < UPPER_PRECEDENCE and then
  3110.         OPERAND.DOWN_LINK.ACROSS_LINK /= null then
  3111.       PRINT("( "); SHOWR(OPERAND); PRINT(" )");
  3112.     else
  3113.       SHOWR(OPERAND);
  3114.     end if;
  3115.   end SHOW_PRECEDENCE;
  3116.  
  3117.   procedure SHOW_MARGIN(F : in FIELD) is
  3118.   begin
  3119.     SHOW_PRECEDENCE(PRECEDENCE(F.OPCODE),F.DOWN_LINK); PRINT_LINE;
  3120.     PRINT(OPERATOR_NAME(F.OPCODE).all &
  3121.         SIX_BLANKS(OPERATOR_NAME(F.OPCODE)'LENGTH..6));
  3122.     SHOW_PRECEDENCE(PRECEDENCE(F.OPCODE),F.DOWN_LINK.ACROSS_LINK);
  3123.   end SHOW_MARGIN;
  3124.  
  3125.   procedure SHOW_LIST(F : in FIELD) is
  3126.   begin
  3127.     SHOWR(F.DOWN_LINK); PRINT(", ");
  3128.     if DOING_SET then
  3129.       PRINT_LINE;
  3130.     end if;
  3131.     SHOWR(F.DOWN_LINK.ACROSS_LINK);
  3132.   end SHOW_LIST;
  3133.  
  3134.   procedure SHOW_OPERATOR(F : in FIELD) is
  3135.   begin
  3136.     case F.OPCODE is
  3137.       when O_SELECT =>
  3138.         SHOW_SELECT(F);
  3139.       when O_INSERT =>
  3140.         SHOW_INSERT(F);
  3141.       when O_DELETE =>
  3142.         SHOW_DELETE(F);
  3143.       when O_UPDATE =>
  3144.         SHOW_UPDATE(F);
  3145.       when O_SUM | O_AVG | O_MAX | O_MIN | O_COUNT =>
  3146.         PRINT(OPERATOR_NAME(F.OPCODE).all & "("); SHOWR(F.DOWN_LINK);
  3147.         PRINT(")");
  3148.       when O_DESC =>
  3149.         SHOWR(F.DOWN_LINK); PRINT(" DESC");
  3150.       when O_IN =>
  3151.         SHOW_PRECEDENCE(PRECEDENCE(O_IN),F.DOWN_LINK); PRINT(" IN ");
  3152.         if F.DOWN_LINK.ACROSS_LINK.FIELD_TYPE /= OPERATOR or else
  3153.              F.DOWN_LINK.ACROSS_LINK.OPCODE /= O_SELECT then
  3154.           PRINT("( "); SHOWR(F.DOWN_LINK.ACROSS_LINK); PRINT(" )");
  3155.         else
  3156.           SHOWR(F.DOWN_LINK.ACROSS_LINK);
  3157.         end if;
  3158.       when O_LIKE | O_EQ | O_NE | O_LT | O_LE | O_GT | O_GE | O_PLUS |
  3159.             O_MINUS | O_TIMES | O_DIV | O_MOD | O_REM | O_POWER =>
  3160.         SHOW_PRECEDENCE(PRECEDENCE(F.OPCODE),F.DOWN_LINK);
  3161.         PRINT(" " & OPERATOR_NAME(F.OPCODE).all & " ");
  3162.         SHOW_PRECEDENCE(PRECEDENCE(F.OPCODE),F.DOWN_LINK.ACROSS_LINK);
  3163.       when O_EXISTS | O_UNARY_PLUS | O_UNARY_MINUS | O_ABS | O_NOT =>
  3164.         PRINT(OPERATOR_NAME(F.OPCODE).all & " ");
  3165.         SHOW_PRECEDENCE(PRECEDENCE(F.OPCODE),F.DOWN_LINK);
  3166.       when O_AND | O_OR =>
  3167.         if F.DOWN_LINK.FIELD_TYPE = OPERATOR and then
  3168.             F.DOWN_LINK.ACROSS_LINK.FIELD_TYPE = OPERATOR then
  3169.           SHOW_MARGIN(F);
  3170.         else
  3171.           SHOW_LIST(F);
  3172.         end if;
  3173.       when O_XOR =>
  3174.         SHOW_MARGIN(F);
  3175.       when O_CAT =>
  3176.         SHOW_LIST(F);
  3177.     end case;
  3178.   end SHOW_OPERATOR;
  3179.  
  3180.   procedure SHOWR(F : in FIELD) is
  3181.     T : TABLE_LIST;
  3182.   begin
  3183.     case F.FIELD_TYPE is
  3184.       when OPERATOR =>
  3185.         SHOW_OPERATOR(F);
  3186.       when INTEGER_LITERAL =>
  3187.         PRINT(F.INTEGER_VALUE);
  3188.       when STRING_LITERAL =>
  3189.         PRINT("'" & F.STRING_VALUE.all & "'");
  3190.       when FLOAT_LITERAL =>
  3191.         PRINT(F.FLOAT_VALUE);
  3192.       when QUALIFIED_FIELD =>
  3193.         SHOW_TABLE_NAME(F.RELATION);
  3194.         PRINT("." & STRING(F.NAME.all));
  3195.       when UNQUALIFIED_FIELD =>
  3196.         PRINT(STRING(F.NAME.all));
  3197.       when FROM_LIST | EMPTY =>
  3198.         null;
  3199.     end case;
  3200.   end SHOWR;
  3201.  
  3202.   procedure SHOW(F : in FIELD) is
  3203.   begin
  3204.     INDENT := -7;
  3205.     SET_CONTINUATION_INDENT(7);
  3206.     BLANK_LINE;
  3207.     INITIAL_TABLE.NAME_LINK := null;
  3208.     INITIAL_TABLE.VERSION_LINK := null;
  3209.     TABLE_TABLE := INITIAL_TABLE;
  3210.     CREATE_TABLE_TABLE(F);
  3211.     if F.ACROSS_LINK /= null then
  3212.       CREATE_TABLE_TABLE(F.ACROSS_LINK);
  3213.     end if;
  3214.     FINALIZE_TABLE_TABLE;
  3215.     SHOWR(F);
  3216.     PRINT_LINE;
  3217.   end SHOW;
  3218.  
  3219. end SHOW_PACKAGE;
  3220. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3221. --main.ada
  3222. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3223. with DATE_DATABASE, SQL_OPERATIONS, TEXT_IO, TEXT_PRINT;
  3224.   use DATE_DATABASE, SQL_OPERATIONS, TEXT_IO, TEXT_PRINT;
  3225.  
  3226. procedure MAIN is
  3227.  
  3228.   subtype FIELD is SQL_OPERATIONS.FIELD;
  3229.  
  3230.   function COUNT(X : STAR_TYPE) return FIELD renames SQL_OPERATIONS.COUNT;
  3231.   function COUNT(F : FIELD)     return FIELD renames SQL_OPERATIONS.COUNT;
  3232.  
  3233.   A : FIELD;
  3234.   L : LINE_TYPE;
  3235.   D : DATABASE_TYPE;
  3236.  
  3237.   procedure SHOW_ACCOUNTS(QUERY : FIELD) is
  3238.     CURSOR      : CURSOR_TYPE;
  3239.     APN         : STRING(1..9);
  3240.     EN_TRY      : INTEGER;
  3241.     DATE        : STRING(1..6);
  3242.     DESCRIPTION : STRING(1..10);
  3243.     TYP         : STRING(1..6);
  3244.     AMOUNT      : FLOAT;
  3245.     BALANCE     : FLOAT;
  3246.     L           : NATURAL;
  3247.  
  3248.     package INT_IO is new INTEGER_IO(INTEGER);
  3249.     package FLT_IO is new FLOAT_IO(FLOAT);
  3250.       use INT_IO, FLT_IO;
  3251.  
  3252.   begin
  3253.     CURSOR := EXECUTE(QUERY);
  3254.     NEW_LINE;
  3255.     loop
  3256.       NEXT_RECORD(CURSOR);
  3257.       DATE        := "      ";
  3258.       DESCRIPTION := "          ";
  3259.       TYP         := "      ";
  3260.       APN := FETCH(CURSOR,1);
  3261.       EN_TRY := FETCH(CURSOR,2);
  3262.       FETCH(CURSOR,3,DATE,L);
  3263.       FETCH(CURSOR,4,DESCRIPTION,L);
  3264.       FETCH(CURSOR,5,TYP,L);
  3265.       AMOUNT := FETCH(CURSOR,6);
  3266.       FETCH(CURSOR,7,BALANCE);
  3267.       PUT(APN);
  3268.       PUT(EN_TRY,4);
  3269.       PUT("  " & DATE & "  " & DESCRIPTION & "  " & TYP);
  3270.       PUT(AMOUNT,5,2,0);
  3271.       PUT(BALANCE,5,2,0);
  3272.       NEW_LINE;
  3273.     end loop;
  3274.   exception
  3275.     when DONE_ERROR =>
  3276.       null;
  3277.   end SHOW_ACCOUNTS;
  3278.  
  3279. begin
  3280.  
  3281.   CREATE_LINE(L,79); SET_LINE(L); D := LOAD_DATABASE("DATE.DAT");
  3282.   SET_DATABASE(D);
  3283.  
  3284.   A := SELEC  ( '*',
  3285.        FROM  => PARCEL_ACCOUNTS);
  3286.  
  3287.   SHOW(A);
  3288.  
  3289.   SHOW_ACCOUNTS(A);
  3290.  
  3291.   A := SELEC  ( '*',
  3292.        FROM  => PARCEL_ACCOUNTS,
  3293.        WHERE => EQ(APN,"93-281-24") );
  3294.  
  3295.   SHOW(A);
  3296.  
  3297.   SHOW_ACCOUNTS(A);
  3298.  
  3299.   A := SELEC  ( '*',
  3300.        FROM  => PARCEL_ACCOUNTS,
  3301.        WHERE => EQ(EN_TRY,7) );
  3302.  
  3303.   SHOW(A);
  3304.  
  3305.   SHOW_ACCOUNTS(A);
  3306.  
  3307.   A := SELEC  ( '*',
  3308.        FROM  => PARCEL_ACCOUNTS,
  3309.        WHERE => EQ(TYP,"CHARGE")
  3310.        AND      EQ(AMOUNT,120.00) );
  3311.  
  3312.   SHOW(A);
  3313.  
  3314.   SHOW_ACCOUNTS(A);
  3315.  
  3316.   A := DELETE (
  3317.        FROM  => PARCEL_ACCOUNTS,
  3318.        WHERE => EQ(TYP,"CHARGE") );
  3319.  
  3320.   SHOW(A);
  3321.  
  3322.   EXECUTE(A);
  3323.  
  3324.   A := SELEC  ( '*',
  3325.        FROM  => PARCEL_ACCOUNTS);
  3326.  
  3327.   SHOW(A);
  3328.  
  3329.   SHOW_ACCOUNTS(A);
  3330.  
  3331.   A := DELETE (
  3332.        FROM  => PARCEL_ACCOUNTS,
  3333.        WHERE => EQ(APN,"93-281-24")
  3334.        AND      EQ(AMOUNT,120.00) );
  3335.  
  3336.   SHOW(A);
  3337.  
  3338.   EXECUTE(A);
  3339.  
  3340.   A := SELEC  ( '*',
  3341.        FROM  => PARCEL_ACCOUNTS);
  3342.  
  3343.   SHOW(A);
  3344.  
  3345.   SHOW_ACCOUNTS(A);
  3346.  
  3347.   A := UPDATE ( PARCEL_ACCOUNTS,
  3348.        SET   => EQ(DESCRIPTION,"BIG BUCKS"),
  3349.        WHERE => EQ(AMOUNT,240.00) );
  3350.  
  3351.   SHOW(A);
  3352.  
  3353.   EXECUTE(A);
  3354.  
  3355.   A := SELEC  ( '*',
  3356.        FROM  => PARCEL_ACCOUNTS);
  3357.  
  3358.   SHOW(A);
  3359.  
  3360.   SHOW_ACCOUNTS(A);
  3361.  
  3362.   A := UPDATE ( PARCEL_ACCOUNTS,
  3363.        SET   => EQ(DESCRIPTION,"DUES82 TOO") &
  3364.                 EQ(BALANCE,0.00),
  3365.        WHERE => EQ(APN,"92-291-44")
  3366.        AND      EQ(DATE,"821212") );
  3367.  
  3368.   SHOW(A);
  3369.  
  3370.   EXECUTE(A);
  3371.  
  3372.   A := SELEC  ( '*',
  3373.        FROM  => PARCEL_ACCOUNTS);
  3374.  
  3375.   SHOW(A);
  3376.  
  3377.   SHOW_ACCOUNTS(A);
  3378.  
  3379.   A := UPDATE ( PARCEL_ACCOUNTS,
  3380.        SET   => EQ(DESCRIPTION,"OOPS") );
  3381.  
  3382.   SHOW(A);
  3383.  
  3384.   EXECUTE(A);
  3385.  
  3386.   A := SELEC  ( '*',
  3387.        FROM  => PARCEL_ACCOUNTS);
  3388.  
  3389.   SHOW(A);
  3390.  
  3391.   SHOW_ACCOUNTS(A);
  3392.  
  3393.   A := DELETE ( PARCEL_ACCOUNTS );
  3394.  
  3395.   SHOW(A);
  3396.  
  3397.   EXECUTE(A);
  3398.  
  3399.   A := SELEC  ( '*',
  3400.        FROM  => PARCEL_ACCOUNTS);
  3401.  
  3402.   SHOW(A);
  3403.  
  3404.   SHOW_ACCOUNTS(A);
  3405.  
  3406.   A := INSERT_INTO ( PARCEL_ACCOUNTS ( APN ),
  3407.               VALUES ( "55-555-55" ) );
  3408.  
  3409.   SHOW(A);
  3410.  
  3411.   EXECUTE(A);
  3412.  
  3413.   A := SELEC  ( '*',
  3414.        FROM  => PARCEL_ACCOUNTS);
  3415.  
  3416.   SHOW(A);
  3417.  
  3418.   SHOW_ACCOUNTS(A);
  3419.  
  3420.   A := INSERT_INTO ( PARCEL_ACCOUNTS ( EN_TRY & DATE & APN ),
  3421.               VALUES => ( 99 and "850411" and "66-666-66" ) );
  3422.  
  3423.   SHOW(A);
  3424.  
  3425.   EXECUTE(A);
  3426.  
  3427.   A := SELEC  ( '*',
  3428.        FROM  => PARCEL_ACCOUNTS);
  3429.  
  3430.   SHOW(A);
  3431.  
  3432.   SHOW_ACCOUNTS(A);
  3433.  
  3434.   A := SELEC  ( '*',      -- Note use of '*' for SELECT *
  3435.        FROM  => CELLAR ); -- Also, SELECT is an Ada reserved word
  3436.  
  3437.   SHOW(A);
  3438.  
  3439.   A := SELEC  ( '*',
  3440.        FROM  => CELLAR,
  3441.        WHERE => EQ(WINE,"Chardonnay") ); -- Note EQ instead of =
  3442.  
  3443.   SHOW(A);
  3444.  
  3445.   A := SELEC  ( BIN & PRODUCER & READY & BOTTLES, -- Note & instead of ,
  3446.        FROM  => CELLAR,
  3447.        WHERE => EQ(WINE,"Chardonnay") ); -- also note " instead of '
  3448.  
  3449.   SHOW(A);
  3450.  
  3451.   A := SELEC  ( '*',
  3452.        FROM  => CELLAR,
  3453.        WHERE => EQ(BIN,3) );
  3454.  
  3455.   SHOW(A);
  3456.  
  3457.   A := SELEC  ( CODE,
  3458.        FROM  => CITIES,
  3459.        WHERE => EQ(CITY,"San Francisco") );
  3460.  
  3461.   SHOW(A);
  3462.  
  3463.   A := SELEC  ( CODE,
  3464.        FROM  => CITIES,
  3465.        WHERE => EQ(CITY,"Chicago") );
  3466.  
  3467.   SHOW(A);
  3468.  
  3469.   A := SELEC  ( '*',
  3470.        FROM  => FLIGHTS,
  3471.        WHERE => EQ(FROM_CODE,"SFO")  -- ultimately, SFO and ORD will be
  3472.        AND      EQ(TO_CODE,"ORD") ); -- values of an enumeration type
  3473.  
  3474.   SHOW(A);
  3475.  
  3476.   A := SELEC  ( '*',
  3477.        FROM  => FLIGHTS,
  3478.        WHERE => EQ(FROM_CODE,
  3479.                    SELEC  ( CODE,
  3480.                    FROM  => CITIES,
  3481.                    WHERE => EQ(CITY,"San Francisco") ) ) -- note SELECT (
  3482.        AND      EQ(TO_CODE,                              -- instead of ( SELECT
  3483.                    SELEC  ( CODE,
  3484.                    FROM  => CITIES,
  3485.                    WHERE => EQ(CITY,"Chicago") ) ) );
  3486.  
  3487.   SHOW(A);
  3488.  
  3489.   A := SELEC  ( '*',
  3490.        FROM  => FLIGHTS,
  3491.        WHERE => EQ(FROM_CODE,
  3492.                    SELEC  ( CODE,
  3493.                    FROM  => CITIES,
  3494.                    WHERE => EQ(CITY,"San Francisco") ) )
  3495.        AND      EQ(TO_CODE,
  3496.                    SELEC  ( CODE,
  3497.                    FROM  => CITIES,
  3498.                    WHERE => EQ(CITY,"Chicago") ) ),
  3499.        ORDER => DEP_TIME );                  -- note ORDER instead of ORDER BY
  3500.  
  3501.   SHOW(A);
  3502.  
  3503.   A := SELEC  ( OWNER,
  3504.        FROM  => PARCELS,
  3505.        WHERE => EQ(APN,"93-282-55") );
  3506.  
  3507.   SHOW(A);
  3508.  
  3509.   A := SELEC  ( AMOUNT,
  3510.        FROM  => PARCEL_ACCOUNTS,
  3511.        WHERE => EQ(APN,"93-282-55")
  3512.        AND      EQ(DESCRIPTION,"PENALTY81")
  3513.        AND      EQ(TYP,"CHARGE") );    -- Date uses TYPE, an Ada reserved word
  3514.  
  3515.   SHOW(A);
  3516.  
  3517.   A := SELEC  ( '*',
  3518.        FROM  => OWNERS,
  3519.        WHERE => LIKE(ADDRESS,"%BERKELEY%") );
  3520.  
  3521.   SHOW(A);
  3522.  
  3523.   A := SELEC  ( EN_TRY + 1,     -- date uses ENTRY, an Ada reserved word
  3524.        FROM  => LAST_ENTRIES,
  3525.        WHERE => EQ(ACCOUNT,"GENERAL") );
  3526.  
  3527.   SHOW(A);
  3528.  
  3529.   A := SELEC  ( '*',
  3530.        FROM  => GENERAL_LEDGER,
  3531.        WHERE => EQ(PARTY,"ROAD FIXERS, INC.")
  3532.        AND      EQ(TYP,"CHARGE") );
  3533.  
  3534.   SHOW(A);
  3535.  
  3536.   A := SELEC  ( SUM(AMOUNT),
  3537.        FROM  => GENERAL_LEDGER,
  3538.        WHERE => EQ(PARTY,"ROAD FIXERS, INC.")
  3539.        AND      EQ(TYP,"CHARGE") );
  3540.  
  3541.   SHOW(A);
  3542.  
  3543.   A := SELEC  ( COUNT('*'),
  3544.        FROM  => PARCEL_ACCOUNTS,
  3545.        WHERE => EQ(APN,"93-282-55")
  3546.        AND      EQ(TYP,"CREDIT")
  3547.        AND      DATE > "811231"
  3548.        AND      DATE < "830101" );
  3549.  
  3550.   SHOW(A);
  3551.  
  3552.   A := SELEC  ( MAX(DATE),
  3553.        FROM  => PARCEL_ACCOUNTS,
  3554.        WHERE => EQ(APN,"93-282-55")
  3555.        AND      EQ(TYP,"CREDIT") );
  3556.  
  3557.   SHOW(A);
  3558.  
  3559.   A := SELEC  ( '*',
  3560.        FROM  => OWNERS,
  3561.        WHERE => EQ(OWNER,
  3562.                    SELEC  ( OWNER,
  3563.                    FROM  => PARCELS,
  3564.                    WHERE => EQ(APN,"93-282-55") ) ) );
  3565.  
  3566.   SHOW(A);
  3567.  
  3568.   A := SELEC  ( APN,
  3569.        FROM  => PARCELS,
  3570.        WHERE => EQ(OWNER,"JOHN MINSKI") );
  3571.  
  3572.   SHOW(A);
  3573.  
  3574.   A := SELEC  ( SUM(AMOUNT),
  3575.        FROM  => PARCEL_ACCOUNTS,
  3576.        WHERE => EQ(TYP,"CREDIT")
  3577.        AND      IS_IN(APN,"93-282-50" or "93-282-51" or "93-282-54" or
  3578.                           "93-282-58") ); -- Ada in may not be overloaded
  3579.                                           -- note or instead of ,
  3580.  
  3581.   SHOW(A);
  3582.  
  3583.   A := SELEC  ( SUM(AMOUNT),
  3584.        FROM  => PARCEL_ACCOUNTS,
  3585.        WHERE => EQ(TYP,"CREDIT")
  3586.        AND      IS_IN(APN,
  3587.                       SELEC  ( APN,
  3588.                       FROM  => PARCELS,
  3589.                       WHERE => EQ(OWNER,"JOHN MINSKI") ) ) );
  3590.  
  3591.   SHOW(A);
  3592.  
  3593.   A := SELEC  ( SAN & EXPLANATION & APN,
  3594.        FROM  => SPECIAL_ASSESSMENTS & PARCELS,          -- note & instead of ,
  3595.        WHERE => EQ(SPECIAL_ASSESSMENTS.ROAD,PARCELS.ROAD) );
  3596.  
  3597.   SHOW(A);
  3598.  
  3599.   A := SELEC  ( PARCELS.APN & OWNERS.OWNER & OWNERS.ADDRESS & OWNERS.PHONE,
  3600.        FROM  => PARCELS & OWNERS,
  3601.        WHERE => EQ(PARCELS.IMPROVED,"Y")        -- should be some BOOLEAN type
  3602.        AND      EQ(PARCELS.OWNER,OWNERS.OWNER),
  3603.        ORDER => OWNERS.OWNER & PARCELS.APN ); -- note & instead of ,
  3604.  
  3605.   SHOW(A);
  3606.  
  3607.   A := SELEC  ( PARCELS.APN & OWNERS.OWNER & OWNERS.ADDRESS & OWNERS.PHONE,
  3608.        FROM  => PARCELS & OWNERS,
  3609.        WHERE => EQ(PARCELS.IMPROVED,"Y")        -- should be some BOOLEAN type
  3610.        AND      EQ(PARCELS.OWNER,OWNERS.OWNER),
  3611.        ORDER => DESC(OWNERS.OWNER) & PARCELS.APN ); -- note DESC( )
  3612.  
  3613.   SHOW(A);
  3614.  
  3615.   A := SELEC  ( APN & OWNER,
  3616.        FROM  => PARCELS,
  3617.        WHERE => EXISTS
  3618.                (SELEC  ( '*',
  3619.                 FROM  => PARCEL_ACCOUNTS,
  3620.                 WHERE => EQ(APN,PARCELS.APN)
  3621.                 AND      EQ(DESCRIPTION,"DUES82")
  3622.                 AND      EQ(TYP,"CREDIT") ) ) );
  3623.  
  3624.   SHOW(A);
  3625.  
  3626.   A := SELEC  ( APN & OWNER,
  3627.        FROM  => PARCELS,
  3628.        WHERE => NOT EXISTS
  3629.                (SELEC  ( '*',
  3630.                 FROM  => PARCEL_ACCOUNTS,
  3631.                 WHERE => EQ(APN,PARCELS.APN)
  3632.                 AND      EQ(DESCRIPTION,"DUES82")
  3633.                 AND      EQ(TYP,"CREDIT") ) ) );
  3634.  
  3635.   SHOW(A);
  3636.  
  3637.   A := SELEC  ( PARTY & SUM(AMOUNT),
  3638.        FROM  => GENERAL_LEDGER,
  3639.        WHERE => EQ(TYP,"CHARGE"),
  3640.        GROUP => PARTY );                -- note GROUP instead of GROUP BY
  3641.  
  3642.   SHOW(A);
  3643.  
  3644.   A := SELEC   ( OWNER,
  3645.        FROM   => PARCELS,
  3646.        GROUP  => OWNER,
  3647.        HAVING => COUNT('*') > 1 );
  3648.  
  3649.   SHOW(A);
  3650.  
  3651.   A := SELEC   ( PARCELS.OWNER & SUM(PARCEL_ACCOUNTS.AMOUNT),
  3652.        FROM   => PARCELS & PARCEL_ACCOUNTS,
  3653.        WHERE  => EQ(PARCELS.APN,PARCEL_ACCOUNTS.APN)
  3654.        AND       EQ(PARCEL_ACCOUNTS.TYP,"CREDIT")
  3655.        AND       LIKE(PARCEL_ACCOUNTS.DATE,"82%"),
  3656.        GROUP  => PARCELS.OWNER,
  3657.        HAVING => SUM(PARCEL_ACCOUNTS.AMOUNT) > 500,
  3658.        ORDER  => PARCELS.OWNER );
  3659.  
  3660.   SHOW(A);
  3661.  
  3662.   A := SELEC  ( APN,
  3663.        FROM  => PARCELS,
  3664.        WHERE => BALANCE < 0 );
  3665.  
  3666.   SHOW(A);
  3667.  
  3668.   A := SELEC  ( OWNER & PHONE,
  3669.        FROM  => OWNERS,
  3670.        WHERE => IS_IN(OWNER,
  3671.                       SELEC  ( OWNER,
  3672.                       FROM  => PARCELS,
  3673.                       WHERE => BALANCE < 0 ) ) );
  3674.  
  3675.   SHOW(A);
  3676.  
  3677.   A := SELEC  ( AVG(AMOUNT),
  3678.        FROM  => GENERAL_LEDGER,
  3679.        WHERE => LIKE(DATE,"82%")
  3680.        AND      EQ(TYP,"CREDIT") );
  3681.  
  3682.   SHOW(A);
  3683.  
  3684.   A := SELEC  ( PARCELS.APN & PARCELS.ROAD & PARCELS.OWNER &
  3685.                 PARCEL_ACCOUNTS.DATE & PARCEL_ACCOUNTS.AMOUNT &
  3686.                 PARCEL_ACCOUNTS.BALANCE,
  3687.        FROM  => PARCELS & PARCEL_ACCOUNTS,
  3688.        WHERE => EQ(PARCELS.APN,PARCEL_ACCOUNTS.APN)
  3689.        AND      EQ(PARCELS.LAST_ENTRY,PARCEL_ACCOUNTS.EN_TRY),
  3690.        ORDER => PARCELS.APN );
  3691.  
  3692.   SHOW(A);
  3693.  
  3694.   A := SELEC  ( APN & OWNER,
  3695.        FROM  => PARCELS,
  3696.        WHERE => EXISTS
  3697.                (SELEC  ( '*',
  3698.                 FROM  => PARCEL_ACCOUNTS,
  3699.                 WHERE => EQ(APN,PARCELS.APN)
  3700.                 AND      EQ(TYP,"CREDIT")
  3701.                 AND      AMOUNT > 499.99 ) ) );
  3702.  
  3703.   SHOW(A);
  3704.  
  3705.   A := SELEC   ( APN,
  3706.        FROM   => PARCEL_ACCOUNTS,
  3707.        WHERE  => EQ(TYP,"CHARGE")
  3708.        AND       DATE > "801231",
  3709.        GROUP  => APN,
  3710.        HAVING => COUNT('*') > 5,
  3711.        ORDER  => APN );
  3712.  
  3713.   SHOW(A);
  3714.  
  3715.   -- This completes Chapter 4 of Date's book, which contains the exposition of
  3716.   -- SQL.  Later chapters do not include any new SQL constructs, so we end our
  3717.   -- examples here.
  3718.  
  3719. end MAIN;
  3720.