
//////////////////////////////////////////////////
//  SQL Server Data Access Components
//  Copyright © 1998-2014 Devart. All right reserved.
//  MS Parser
//////////////////////////////////////////////////

{$IFNDEF CLR}

{$I Sdac.inc}

unit MSParserUni;
{$ENDIF}

interface
uses
  CRParser, CRTypes;

const
  lxMSFirst  = 1000;
  lxALTER    = lxMSFirst;
  lxCOMPUTE  = lxALTER + 1;
  lxCREATE   = lxCOMPUTE + 1;
  lxCROSS    = lxCREATE + 1;
  lxDECLARE  = lxCROSS + 1;
  lxDEFAULT  = lxDECLARE + 1;
  lxEND      = lxDEFAULT + 1;
  lxFUNCTION = lxEND + 1;
  lxGO       = lxFUNCTION + 1;
  lxOPTION   = lxGO + 1;
  lxPROCEDURE = lxOPTION + 1;
  lxREPLACE  = lxPROCEDURE + 1;
  lxRULE     = lxREPLACE + 1;
  lxTABLE    = lxRULE + 1;
  lxTOP      = lxTABLE + 1;
  lxTRIGGER  = lxTOP + 1;
  lxVIEW     = lxTRIGGER + 1;

type
  TMSParser = class (TSQLParser)
  protected
    function IsIdentQuote(Ch: Char): boolean; override;
    procedure ToRightQuote(LeftQuote: Char); override; // Search right quote of quoted string value or quoted identifier

    procedure InitParser; override;
  end;

implementation

uses
  Classes, SysUtils;

var
  MSKeywordLexems: TIntValueStringList;

{ TMSParser }

procedure TMSParser.InitParser;
begin
  inherited;
(*
SELECT statement ::=
    < query_expression >
    [ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }
        [ ,...n ]    ]
    [ COMPUTE
        { { AVG | COUNT | MAX | MIN | SUM } ( expression ) } [ ,...n ]
        [ BY expression [ ,...n ] ]
    ]
    [ FOR { BROWSE | XML { RAW | AUTO | EXPLICIT }
            [ , XMLDATA ]
            [ , ELEMENTS ]
            [ , BINARY base64 ]
        }
]
    [ OPTION ( < query_hint > [ ,...n ]) ]

< query expression > ::=
    { < query specification > | ( < query expression > ) }
    [ UNION [ ALL ] < query specification | ( < query expression > ) [...n ] ]

< query specification > ::=
    SELECT [ ALL | DISTINCT ]
        [ { TOP integer | TOP integer PERCENT } [ WITH TIES ] ]
        < select_list >
    [ INTO new_table ]
    [ FROM { < table_source > } [ ,...n ] ]
    [ WHERE < search_condition > ]
    [ GROUP BY [ ALL ] group_by_expression [ ,...n ]
        [ WITH { CUBE | ROLLUP } ]
    ]
    [ HAVING < search_condition > ]

*)

  SetLength(FClauses, 7);
  FClauses[0] := lxWHERE;
  FClauses[1] := lxGROUP;
  FClauses[2] := lxHAVING;
  FClauses[3] := lxORDER;
  FClauses[4] := lxCOMPUTE;
  FClauses[5] := lxFOR;
  FClauses[6] := lxOPTION;

  FKeywordLexems := MSKeywordLexems;

  CommentBegin := '/*';
  CommentEnd := '*/';
end;

function TMSParser.IsIdentQuote(Ch: Char): boolean;
begin
  case Ch of
    '"', '[', ']':
      Result := True;
    else
      Result := False;
  end;
end;

procedure TMSParser.ToRightQuote(LeftQuote: Char);
begin
  if LeftQuote = '[' then
    inherited ToRightQuote(']')
  else
    inherited;
end;

initialization
  MSKeywordLexems := TIntValueStringList.Create;
  MSKeywordLexems.Assign(SQLKeywordLexems);

  MSKeywordLexems.Add('ALTER', lxALTER);
  MSKeywordLexems.Add('COMPUTE', lxCOMPUTE);
  MSKeywordLexems.Add('CREATE', lxCREATE);
  MSKeywordLexems.Add('CROSS', lxCROSS);
  MSKeywordLexems.Add('DECLARE', lxDECLARE);
  MSKeywordLexems.Add('DEFAULT', lxDEFAULT);
  MSKeywordLexems.Add('END', lxEND);
  MSKeywordLexems.Add('FUNCTION', lxFUNCTION);
  MSKeywordLexems.Add('GO', lxGO);
  MSKeywordLexems.Add('OPTION', lxOPTION);
  MSKeywordLexems.Add('PROCEDURE', lxPROCEDURE);
  MSKeywordLexems.Add('REPLACE', lxREPLACE);
  MSKeywordLexems.Add('RULE', lxRULE);
  MSKeywordLexems.Add('TABLE', lxTABLE);
  MSKeywordLexems.Add('TOP', lxTOP);
  MSKeywordLexems.Add('TRIGGER', lxTRIGGER);
  MSKeywordLexems.Add('VIEW', lxVIEW);

  MSKeywordLexems.Sort;

finalization
  MSKeywordLexems.Free;

end.
