Browse Source

sql parser: fallback for all parser keywords to identifiers/functions if they are used in an expression (e.g. LEFT was affected)

git-svn-id: trunk@46446 -
(cherry picked from commit bcde18f8797fc1a0b06819ced39907433d367c83)
ondrej 5 years ago
parent
commit
7d4dd4f12c
2 changed files with 32 additions and 3 deletions
  1. 6 3
      packages/fcl-db/src/sql/fpsqlparser.pas
  2. 26 0
      packages/fcl-db/tests/tcparser.pas

+ 6 - 3
packages/fcl-db/src/sql/fpsqlparser.pas

@@ -2880,7 +2880,10 @@ begin
         Result:=TSQLAsteriskExpression(CreateElement(TSQLAsteriskExpression,APArent));
         GetNextToken;
         end;
-      tsqlIdentifier:
+    else
+      // some keywords (FirstKeyword..LastKeyWord) can also be functions/identifiers (LEFT, RIGHT)
+      //   To-Do: remove some of them if necessary
+      if CurrentToken in [tsqlIdentifier, FirstKeyword..LastKeyWord] then
         begin
         N:=CurrentTokenString;
         If (GetNextToken<>tsqlBraceOpen) then
@@ -2941,10 +2944,10 @@ begin
           TSQLFunctionCallExpression(Result).IDentifier:=N;
           TSQLFunctionCallExpression(Result).Arguments:=L;
           end;
-        end;
+        end
       else
         UnexpectedToken;
-      end;
+    end;
   except
     FreeAndNil(Result);
     Raise;

+ 26 - 0
packages/fcl-db/tests/tcparser.pas

@@ -450,6 +450,7 @@ type
     procedure TestAggregateAvgDistinct;
     procedure TestUpperConst;
     procedure TestUpperError;
+    procedure TestLeft;
     procedure TestGenID;
     procedure TestGenIDError1;
     procedure TestGenIDError2;
@@ -4778,6 +4779,31 @@ begin
   AssertAggregateExpression(H.Left,afCount,'C',aoNone);
 end;
 
+procedure TTestSelectParser.TestLeft;
+
+Var
+  E : TSQLFunctionCallExpression;
+  L : TSQLLiteralExpression;
+  S : TSQLStringLiteral;
+  I : TSQLIntegerLiteral;
+
+begin
+  TestSelect('SELECT LEFT(''abc'', 1) FROM A');
+  AssertEquals('One field',1,Select.Fields.Count);
+  AssertEquals('One table',1,Select.Tables.Count);
+  AssertTable(Select.Tables[0],'A');
+  CheckClass(Select.Fields[0],TSQLSelectField);
+  E:=TSQLFunctionCallExpression(CheckClass(TSQLSelectField(Select.Fields[0]).Expression,TSQLFunctionCallExpression));
+  AssertEquals('LEFT function name','LEFT',E.Identifier);
+  AssertEquals('Two function elements',2,E.Arguments.Count);
+  L:=TSQLLiteralExpression(CheckClass(E.Arguments[0],TSQLLiteralExpression));
+  S:=TSQLStringLiteral(CheckClass(L.Literal,TSQLStringLiteral));
+  AssertEquals('Correct string constant','abc',S.Value);
+  L:=TSQLLiteralExpression(CheckClass(E.Arguments[1],TSQLLiteralExpression));
+  I:=TSQLIntegerLiteral(CheckClass(L.Literal,TSQLIntegerLiteral));
+  AssertEquals('Correct integer constant',1,I.Value);
+end;
+
 procedure TTestSelectParser.TestNoTable;
 
 Var