PageRenderTime 121ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/ecl/hql/hqlgram.y

https://github.com/emuharemagic/HPCC-Platform
Happy | 10874 lines | 10241 code | 633 blank | 0 comment | 0 complexity | 6b411853aeb8dcaf51238ca55dab6420 MD5 | raw file
  1. //
  2. // HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //############################################################################## */
  16. //Either api.pure of c++ skeleton could be used, not both (which causes an error).
  17. //Note the c++ generation still generates a separate class for the raw processing from the HqlGram class, so whichever is
  18. //used the productions need to use parser->... to access the context
  19. %define api.pure
  20. //%error-verbose
  21. %lex-param {HqlGram* parser}
  22. %lex-param {int * yyssp}
  23. %parse-param {HqlGram* parser}
  24. %name-prefix "eclyy"
  25. //
  26. %destructor {$$.release();} <>
  27. //Could override destructors for all tokens e.g.,
  28. //%destructor {} ABS
  29. //but warnings still come out, and improvement in code is marginal.
  30. //Only defining destructors for those productions that need them would solve it, but be open to missing items.
  31. //Adding a comment to reference unused parameters also fails to solve it because it ignores references in comments (and a bit ugly)
  32. //fixing bison to ignore destructor {} for need use is another alternative - but would take a long time to feed into a public build.
  33. %{
  34. #include "platform.h"
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include "hql.hpp"
  38. #include "jlib.hpp"
  39. #include "jmisc.hpp"
  40. #include "jexcept.hpp"
  41. #include "hqlerrors.hpp"
  42. #include "hqlgram.hpp"
  43. #include "hqlfold.hpp"
  44. #include "hqlpmap.hpp"
  45. #include "hqlutil.hpp"
  46. #include "hqlattr.hpp"
  47. #include "hqlmeta.hpp"
  48. #define REDEF_MSG(name) StringBuffer msg; \
  49. msg.append(w"Identifier '"); \
  50. msg.append(name.queryExpr()->queryName()->str()); \
  51. msg.append("' before := "); \
  52. msg.append(" is already defined"); \
  53. parser->reportError(ERR_ID_REDEFINE, name, msg.str())
  54. #define REDEF_ERROR(name) \
  55. { \
  56. REDEF_MSG(name); \
  57. }
  58. #define REDEF_ERROR1(name,e1) \
  59. { \
  60. REDEF_MSG(name); \
  61. e1.release(); \
  62. }
  63. #define REDEF_ERROR2(name,e1,e2) \
  64. { \
  65. REDEF_MSG(name); \
  66. e1.release(); \
  67. e2.release(); \
  68. }
  69. #define REDEF_ERROR3(name,e1,e2,e3) \
  70. { \
  71. REDEF_MSG(name); \
  72. e1.release(); \
  73. e2.release(); \
  74. e3.release(); \
  75. }
  76. inline int eclyylex(attribute * yylval, HqlGram* parser, const short int * yyssp)
  77. {
  78. return parser->yyLex(yylval, yyssp);
  79. }
  80. static void eclsyntaxerror(HqlGram * parser, const char * s, short yystate, int token);
  81. #define eclyyerror(parser, s) eclsyntaxerror(parser, s, yystate, yychar)
  82. #define ignoreBisonWarning(x)
  83. #define ignoreBisonWarnings2(x,y)
  84. #define ignoreBisonWarnings3(x,y,z)
  85. %}
  86. //=========================================== tokens ====================================
  87. %token
  88. /* remember to add any new tokens to the error reporter and lexer too! */
  89. /* If they clash with other #defines etc then use TOK_ as a prefix */
  90. ABS
  91. ACOS
  92. AFTER
  93. AGGREGATE
  94. ALIAS
  95. ALL
  96. ALLNODES
  97. AND
  98. ANY
  99. APPLY
  100. _ARRAY_
  101. AS
  102. ASCII
  103. ASIN
  104. TOK_ASSERT
  105. ASSTRING
  106. ATAN
  107. ATAN2
  108. ATMOST
  109. AVE
  110. BACKUP
  111. BEFORE
  112. BEST
  113. BETWEEN
  114. TOK_BITMAP
  115. BIG
  116. BLOB
  117. BNOT
  118. BUILD
  119. CARDINALITY
  120. CASE
  121. TOK_CATCH
  122. CHECKPOINT
  123. CHOOSE
  124. CHOOSEN
  125. CHOOSENALL
  126. CHOOSESETS
  127. CLUSTER
  128. CLUSTERSIZE
  129. COGROUP
  130. __COMMON__
  131. __COMPOUND__
  132. COMBINE
  133. COMPRESSED
  134. __COMPRESSED__
  135. TOK_CONST
  136. CORRELATION
  137. COS
  138. COSH
  139. COUNT
  140. COUNTER
  141. COVARIANCE
  142. CPPBODY
  143. CRC
  144. CRON
  145. CSV
  146. DATASET
  147. __DEBUG__
  148. DEDUP
  149. DEFAULT
  150. DEFINE
  151. DENORMALIZE
  152. DEPRECATED
  153. DESC
  154. DICTIONARY
  155. DISTRIBUTE
  156. DISTRIBUTED
  157. DISTRIBUTION
  158. DYNAMIC
  159. EBCDIC
  160. ECLCRC
  161. ELSE
  162. ELSEIF
  163. EMBED
  164. EMBEDDED
  165. _EMPTY_
  166. ENCODING
  167. ENCRYPT
  168. ENCRYPTED
  169. END
  170. ENDCPP
  171. ENDEMBED
  172. ENTH
  173. ENUM
  174. TOK_ERROR
  175. ESCAPE
  176. EVALUATE
  177. EVENT
  178. EVENTEXTRA
  179. EVENTNAME
  180. EXCEPT
  181. EXCLUSIVE
  182. EXISTS
  183. EXP
  184. EXPIRE
  185. EXPORT
  186. EXTEND
  187. FAIL
  188. FAILCODE
  189. FAILMESSAGE
  190. FAILURE
  191. TOK_FALSE
  192. FEATURE
  193. FETCH
  194. FEW
  195. FILEPOSITION
  196. FILTERED
  197. FIRST
  198. TOK_FIXED
  199. FLAT
  200. FROM
  201. FORMAT_ATTR
  202. FORWARD
  203. FROMUNICODE
  204. FROMXML
  205. FULL
  206. FUNCTION
  207. GETENV
  208. GLOBAL
  209. GRAPH
  210. GROUP
  211. GROUPBY
  212. GROUPED
  213. __GROUPED__
  214. GUARD
  215. HASH
  216. HASH32
  217. HASH64
  218. HASHMD5
  219. HAVING
  220. HEADING
  221. HINT
  222. HOLE
  223. HTTPCALL
  224. HTTPHEADER
  225. IF
  226. IFF
  227. IFBLOCK
  228. TOK_IGNORE
  229. IMPLEMENTS
  230. IMPORT
  231. INDEPENDENT
  232. INLINE
  233. TOK_IN
  234. INNER
  235. INTERFACE
  236. INTERNAL
  237. INTFORMAT
  238. ISNULL
  239. ISVALID
  240. ITERATE
  241. JOIN
  242. JOINED
  243. KEEP
  244. KEYDIFF
  245. KEYED
  246. KEYPATCH
  247. KEYUNICODE
  248. LABELED
  249. LAST
  250. LEFT
  251. LENGTH
  252. LIBRARY
  253. LIMIT
  254. LINKCOUNTED
  255. LITERAL
  256. LITTLE
  257. LN
  258. LOADXML
  259. LOCAL
  260. LOCALE
  261. LOCALFILEPOSITION
  262. TOK_LOG
  263. LOGICALFILENAME
  264. LOOKUP
  265. LOOP
  266. LZW
  267. MANY
  268. MAP
  269. MATCHED
  270. MATCHLENGTH
  271. MATCHPOSITION
  272. MATCHROW
  273. MATCHTEXT
  274. MATCHUNICODE
  275. MATCHUTF8
  276. MAX
  277. MAXCOUNT
  278. MAXLENGTH
  279. MAXSIZE
  280. MERGE
  281. MERGE_ATTR
  282. MERGEJOIN
  283. MIN
  284. MODULE
  285. MOFN
  286. MULTIPLE
  287. NAMED
  288. NAMEOF
  289. NAMESPACE
  290. NOBOUNDCHECK
  291. NOCASE
  292. NOFOLD
  293. NOHOIST
  294. NOLOCAL
  295. NONEMPTY
  296. NOOVERWRITE
  297. NORMALIZE
  298. NOROOT
  299. NOSCAN
  300. NOSORT
  301. __NOSTREAMING__
  302. NOT
  303. NOTHOR
  304. NOTIFY
  305. NOTRIM
  306. NOXPATH
  307. OF
  308. OMITTED
  309. ONCE
  310. ONFAIL
  311. ONLY
  312. ONWARNING
  313. OPT
  314. OR
  315. ORDERED
  316. OUTER
  317. OUTPUT
  318. TOK_OUT
  319. OVERWRITE
  320. __OWNED__
  321. PACKED
  322. PARALLEL
  323. PARSE
  324. PARTITION
  325. PARTITION_ATTR
  326. TOK_PATTERN
  327. PENALTY
  328. PERSIST
  329. PHYSICALFILENAME
  330. PIPE
  331. __PLATFORM__
  332. POWER
  333. PREFETCH
  334. PRELOAD
  335. PRIORITY
  336. PRIVATE
  337. PROCESS
  338. PROJECT
  339. PROXYADDRESS
  340. PULL
  341. PULLED
  342. QUOTE
  343. RANDOM
  344. RANGE
  345. RANK
  346. RANKED
  347. REALFORMAT
  348. RECORD
  349. RECORDOF
  350. RECOVERY
  351. REGEXFIND
  352. REGEXREPLACE
  353. REGROUP
  354. REJECTED
  355. RELATIONSHIP
  356. REMOTE
  357. REPEAT
  358. RESPONSE
  359. RETRY
  360. RETURN
  361. RIGHT
  362. RIGHT_NN
  363. ROLLUP
  364. ROUND
  365. ROUNDUP
  366. ROW
  367. ROWS
  368. ROWSET
  369. ROWDIFF
  370. RULE
  371. SAMPLE
  372. SCAN
  373. SECTION
  374. SELF
  375. SEPARATOR
  376. __SEQUENCE__
  377. SEQUENTIAL
  378. SERVICE
  379. SET
  380. SHARED
  381. SIMPLE_TYPE
  382. SIN
  383. SINGLE
  384. SINH
  385. SIZEOF
  386. SKEW
  387. SKIP
  388. SMART
  389. SOAPACTION
  390. SOAPCALL
  391. SORT
  392. SORTED
  393. SQL
  394. SQRT
  395. STABLE
  396. __STAND_ALONE__
  397. STEPPED
  398. STORED
  399. STREAMED
  400. SUBSORT
  401. SUCCESS
  402. SUM
  403. SWAPPED
  404. TABLE
  405. TAN
  406. TANH
  407. TERMINATOR
  408. THEN
  409. THISNODE
  410. THOR
  411. THRESHOLD
  412. TIMEOUT
  413. TIMELIMIT
  414. TOKEN
  415. TOPN
  416. TOUNICODE
  417. TOXML
  418. TRANSFER
  419. TRANSFORM
  420. TRIM
  421. TRUNCATE
  422. TOK_TRUE
  423. TYPE
  424. TYPEOF
  425. UNICODEORDER
  426. UNGROUP
  427. UNORDERED
  428. UNSIGNED
  429. UNSORTED
  430. UNSTABLE
  431. UPDATE
  432. USE
  433. VALIDATE
  434. VARIANCE
  435. VIRTUAL
  436. WAIT
  437. TOK_WARNING
  438. WHEN
  439. WHICH
  440. WIDTH
  441. WILD
  442. WITHIN
  443. WHOLE
  444. WORKUNIT
  445. XML_TOKEN
  446. XMLDECODE
  447. XMLDEFAULT
  448. XMLENCODE
  449. XMLPROJECT
  450. XMLTEXT
  451. XMLUNICODE
  452. XPATH
  453. //Operators
  454. FIELD_REF
  455. FIELDS_REF
  456. ANDAND
  457. EQ
  458. NE
  459. LE
  460. LT
  461. GE
  462. GT
  463. ORDER
  464. ASSIGN
  465. GOESTO
  466. DOTDOT
  467. DIV
  468. SHIFTL
  469. SHIFTR
  470. DATAROW_ID
  471. DATASET_ID
  472. DICTIONARY_ID
  473. SCOPE_ID
  474. VALUE_ID
  475. VALUE_ID_REF
  476. ACTION_ID
  477. UNKNOWN_ID
  478. RECORD_ID
  479. ALIEN_ID
  480. TRANSFORM_ID
  481. PATTERN_ID
  482. FEATURE_ID
  483. EVENT_ID
  484. ENUM_ID
  485. LIST_DATASET_ID
  486. SORTLIST_ID
  487. TYPE_ID
  488. SET_TYPE_ID
  489. PATTERN_TYPE_ID
  490. DATASET_TYPE_ID
  491. DICTIONARY_TYPE_ID
  492. DATAROW_FUNCTION
  493. DATASET_FUNCTION
  494. DICTIONARY_FUNCTION
  495. VALUE_FUNCTION
  496. ACTION_FUNCTION
  497. PATTERN_FUNCTION
  498. RECORD_FUNCTION
  499. EVENT_FUNCTION
  500. SCOPE_FUNCTION
  501. TRANSFORM_FUNCTION
  502. LIST_DATASET_FUNCTION
  503. VALUE_MACRO
  504. DEFINITIONS_MACRO
  505. BOOL_CONST
  506. INTEGER_CONST
  507. STRING_CONST
  508. DATA_CONST
  509. REAL_CONST
  510. UNICODE_CONST
  511. TYPE_LPAREN
  512. TYPE_RPAREN
  513. MACRO
  514. COMPLEX_MACRO
  515. ENDMACRO
  516. SKIPPED
  517. HASHEND
  518. HASHELIF
  519. HASHBREAK
  520. INDEX
  521. HASH_CONSTANT
  522. HASH_OPTION
  523. HASH_WORKUNIT
  524. HASH_STORED
  525. HASH_LINK
  526. HASH_ONWARNING
  527. INTERNAL_READ_NEXT_TOKEN
  528. // __INTERNAL__HASHDEFINED_FOUND
  529. // __INTERNAL__HASHDEFINED_NOTFOUND
  530. /* add new token before this! */
  531. YY_LAST_TOKEN
  532. %left LOWEST_PRECEDENCE
  533. %left VALUE_MACRO
  534. %left OR
  535. %left AND
  536. %left reduceAttrib
  537. %left ORDER UNICODEORDER
  538. %left SHIFTL SHIFTR
  539. %left '+' '-'
  540. %left '*' '/' '%' DIV
  541. %left '|' '^'
  542. %left '&' ANDAND
  543. %left NOT
  544. %left '.'
  545. %left '('
  546. %left '['
  547. %left HIGHEST_PRECEDENCE
  548. %%
  549. //================================== begin of syntax section ==========================
  550. hqlQuery
  551. : ENCRYPTED hqlQueryBody { ignoreBisonWarnings3($$,$1,$2); }
  552. | hqlQueryBody
  553. ;
  554. hqlQueryBody
  555. : definitions
  556. | query
  557. { parser->addResult($1.getExpr(), $1); $$.clear(); }
  558. | definitions query
  559. {
  560. ignoreBisonWarning($1);
  561. parser->addResult($2.getExpr(), $2); $$.clear();
  562. }
  563. | RETURN goodObject ';'
  564. { parser->addResult($2.getExpr(), $2); $$.clear(); }
  565. | definitions setActiveToExpected RETURN goodObject ';'
  566. { parser->addResult($4.getExpr(), $4); $$.clear(); }
  567. | compoundModule ';'
  568. { parser->addResult($1.getExpr(), $1); $$.clear(); }
  569. //Temporary productions...
  570. | recordDef ';'
  571. {
  572. ignoreBisonWarning($2);
  573. parser->addResult($1.getExpr(), $1); $$.clear();
  574. }
  575. | definitions recordDef ';'
  576. {
  577. ignoreBisonWarnings2($1, $3);
  578. parser->addResult($2.getExpr(), $2); $$.clear();
  579. }
  580. |
  581. //Special production used processing template queries
  582. | GOESTO goodObject ';'
  583. { parser->addResult($2.getExpr(), $2); $$.clear(); }
  584. ;
  585. setActiveToExpected
  586. : { parser->setCurrentToExpected(); $$.clear(); }
  587. ;
  588. importSection
  589. : startIMPORT importItem endIMPORT
  590. { parser->lastpos = $3.pos.position+1; $$.clear(); }
  591. | startIMPORT error endIMPORT
  592. { parser->lastpos = $3.pos.position+1; $$.clear(); }
  593. ;
  594. startIMPORT
  595. : IMPORT { parser->setIdUnknown(true); $$.clear(); }
  596. ;
  597. endIMPORT
  598. : ';' { parser->setIdUnknown(false); $$.clear(); }
  599. ;
  600. importItem
  601. : importSelectorList
  602. {
  603. parser->processImport($1, NULL);
  604. $$.clear();
  605. }
  606. | importSelectorList FROM importSelector
  607. {
  608. parser->processImport($1, $3, NULL);
  609. $$.clear();
  610. }
  611. | importSelectorList AS UNKNOWN_ID
  612. {
  613. parser->processImport($1, $3.getId());
  614. $$.clear();
  615. }
  616. | importSelectorList FROM importSelector AS UNKNOWN_ID
  617. {
  618. parser->processImport($1, $3, $5.getId());
  619. $$.clear();
  620. }
  621. | '*' FROM importSelector
  622. {
  623. parser->processImportAll($3);
  624. $$.clear();
  625. }
  626. | importSelectorList AS '*'
  627. {
  628. if (queryLegacyImportSemantics())
  629. parser->reportWarning(ERR_DEPRECATED, $1.pos, "IMPORT <module> AS * is deprecated, use IMPORT * FROM <module>");
  630. else
  631. parser->reportError(ERR_DEPRECATED, $1.pos, "IMPORT <module> AS * is deprecated, use IMPORT * FROM <module>");
  632. parser->processImportAll($1);
  633. $$.clear();
  634. }
  635. ;
  636. importSelectorList
  637. : beginList importItems
  638. {
  639. HqlExprArray importItems;
  640. parser->endList(importItems);
  641. $$.setExpr(createComma(importItems), $2);
  642. }
  643. ;
  644. importItems
  645. : importSelector
  646. {
  647. parser->addListElement($1.getExpr());
  648. $$.clear();
  649. }
  650. | importItems ',' importSelector
  651. {
  652. parser->addListElement($3.getExpr());
  653. $$.clear();
  654. }
  655. ;
  656. importSelector
  657. : importId;
  658. importId
  659. : UNKNOWN_ID {
  660. $$.setExpr(createId($1.getId()), $1);
  661. }
  662. | '$' {
  663. $$.setExpr(createAttribute(selfAtom), $1);
  664. }
  665. | importId '.' UNKNOWN_ID
  666. {
  667. $$.setExpr(createAttribute(_dot_Atom, $1.getExpr(), createId($3.getId())), $1);
  668. }
  669. | importId '.' '^'
  670. {
  671. $$.setExpr(createAttribute(_container_Atom, $1.getExpr()), $1);
  672. }
  673. ;
  674. defineType
  675. : typeDef
  676. | setType
  677. | explicitDatasetType
  678. | explicitDictionaryType
  679. | ROW {
  680. IHqlExpression* record = queryNullRecord();
  681. $$.setType(makeRowType(record->getType()));
  682. $$.setPosition($1);
  683. }
  684. | transformType
  685. ;
  686. explicitDatasetType
  687. : explicitDatasetType1
  688. | GROUPED explicitDatasetType1
  689. {
  690. $$.setType(makeGroupedTableType($2.getType()));
  691. $$.setPosition($1);
  692. }
  693. ;
  694. explicitDatasetType1
  695. : DATASET
  696. {
  697. $$.setType(makeTableType(makeRowType(queryNullRecord()->getType())));
  698. $$.setPosition($1);
  699. }
  700. | DATASET '(' recordDef childDatasetOptions ')'
  701. {
  702. OwnedHqlExpr record = $3.getExpr();
  703. OwnedHqlExpr options = $4.getExpr();
  704. ITypeInfo * recordType = createRecordType(record);
  705. Owned<ITypeInfo> tableType = makeTableType(makeRowType(recordType));
  706. if (options)
  707. tableType.setown(makeAttributeModifier(LINK(tableType), createAttribute(_childAttr_Atom, LINK(options))));
  708. $$.setType(tableType.getClear());
  709. $$.setPosition($1);
  710. }
  711. | _ARRAY_ explicitDatasetType
  712. {
  713. $$.setType(makeOutOfLineModifier($2.getType()));
  714. $$.setPosition($1);
  715. }
  716. | LINKCOUNTED explicitDatasetType
  717. {
  718. Owned<ITypeInfo> dsType = $2.getType();
  719. $$.setType(setLinkCountedAttr(dsType, true));
  720. $$.setPosition($1);
  721. }
  722. | STREAMED explicitDatasetType
  723. {
  724. Owned<ITypeInfo> dsType = $2.getType();
  725. Owned<ITypeInfo> linkedType = setLinkCountedAttr(dsType, true);
  726. $$.setType(setStreamedAttr(linkedType, true));
  727. $$.setPosition($1);
  728. }
  729. | EMBEDDED explicitDatasetType
  730. {
  731. $$.setType(makeAttributeModifier($2.getType(), getEmbeddedAttr()));
  732. $$.setPosition($1);
  733. }
  734. | userTypedefDataset
  735. ;
  736. explicitDictionaryType
  737. : DICTIONARY
  738. {
  739. $$.setType(makeDictionaryType(makeRowType(queryNullRecord()->getType())));
  740. $$.setPosition($1);
  741. }
  742. | DICTIONARY '(' recordDef ')'
  743. {
  744. OwnedHqlExpr record = $3.getExpr();
  745. ITypeInfo * recordType = createRecordType(record);
  746. $$.setType(makeDictionaryType(makeRowType(recordType)));
  747. $$.setPosition($1);
  748. }
  749. | LINKCOUNTED explicitDictionaryType
  750. {
  751. Owned<ITypeInfo> dsType = $2.getType();
  752. $$.setType(setLinkCountedAttr(dsType, true));
  753. $$.setPosition($1);
  754. }
  755. | userTypedefDictionary
  756. ;
  757. explicitRowType
  758. : explicitRowType1
  759. | LINKCOUNTED explicitRowType1
  760. {
  761. Owned<ITypeInfo> rowType = $2.getType();
  762. $$.setType(setLinkCountedAttr(rowType, true));
  763. $$.setPosition($1);
  764. }
  765. ;
  766. explicitRowType1
  767. : ROW {
  768. IHqlExpression* record = queryNullRecord();
  769. $$.setType(makeRowType(record->getType()));
  770. $$.setPosition($1);
  771. }
  772. | ROW '(' recordDef ')'
  773. {
  774. OwnedHqlExpr record = $3.getExpr();
  775. $$.setType(makeRowType(record->getType()));
  776. $$.setPosition($1);
  777. }
  778. ;
  779. transformType
  780. : TRANSFORM '(' recordDef ')'
  781. {
  782. OwnedHqlExpr record = $3.getExpr();
  783. $$.setType(makeTransformType(LINK(record->queryRecordType())), $1);
  784. }
  785. | TRANSFORM '(' dataSet ')'
  786. {
  787. OwnedHqlExpr ds = $3.getExpr();
  788. $$.setType(makeTransformType(LINK(ds->queryRecordType())), $1);
  789. }
  790. ;
  791. propType
  792. : simpleType /* only simple type is supported for service */
  793. | scopeFlag simpleType
  794. {
  795. parser->reportError(ERR_SVC_NOSCOPEMODIFIER,$1,"Function in service can not specify EXPORT or SHARED");
  796. $$.setType($2.getType());
  797. }
  798. | scopeFlag {
  799. parser->reportError(ERR_SVC_NOSCOPEMODIFIER,$1,"Function in service can not specify EXPORT or SHARED");
  800. $$.setType(makeVoidType());
  801. }
  802. ;
  803. paramType
  804. : typeDef
  805. {
  806. OwnedITypeInfo type = $1.getType();
  807. //Syntactic oddity. A record means a row of that record type.
  808. if (type->getTypeCode() == type_record)
  809. type.setown(makeRowType(type.getClear()));
  810. $$.setType(type.getClear());
  811. $$.setPosition($1);
  812. }
  813. | DATASET_ID {
  814. OwnedHqlExpr dataset = $1.getExpr();
  815. // $$.setType(makeOriginalModifier(createRecordType(dataset), LINK(dataset)));
  816. $$.setType(makeRowType(createRecordType(dataset)));
  817. $$.setPosition($1);
  818. }
  819. | moduleScopeDot DATASET_ID leaveScope
  820. {
  821. //slightly nasty to add two original modifiers to the record, but the first one allows
  822. //us to get the record right, and the second the types of parameters on transforms.
  823. $1.release();
  824. OwnedHqlExpr dataset = $2.getExpr();
  825. //$$.setType(makeOriginalModifier(createRecordType(dataset), LINK(dataset)));
  826. $$.setType(makeRowType(createRecordType(dataset)));
  827. $$.setPosition($2);
  828. }
  829. | abstractDataset {
  830. OwnedHqlExpr record = $1.getExpr();
  831. OwnedHqlExpr abstractRecord = createAbstractRecord(record);
  832. OwnedITypeInfo type = makeTableType(makeRowType(abstractRecord->getType()));
  833. $$.setType(type.getClear(), $1);
  834. parser->setTemplateAttribute();
  835. }
  836. | explicitDatasetType
  837. | explicitDictionaryType
  838. | explicitRowType
  839. | abstractModule
  840. {
  841. OwnedHqlExpr scope = $1.getExpr();
  842. $$.setType(scope->getType()); // more what about if moduleScope is a parameter?
  843. $$.setPosition($1);
  844. }
  845. | patternParamType
  846. | VIRTUAL RECORD
  847. {
  848. IHqlExpression* record = queryNullRecord();
  849. OwnedHqlExpr abstractRecord = createAbstractRecord(record);
  850. $$.setType(abstractRecord->getType(), $1);
  851. parser->setTemplateAttribute();
  852. }
  853. ;
  854. patternParamType
  855. : TOK_PATTERN {
  856. $$.setType(makePatternType());
  857. $$.setPosition($1);
  858. }
  859. | RULE {
  860. $$.setType(makeRuleType(NULL));
  861. $$.setPosition($1);
  862. }
  863. | TOKEN {
  864. $$.setType(makeTokenType());
  865. $$.setPosition($1);
  866. }
  867. ;
  868. object
  869. : goodObject
  870. | badObject
  871. ;
  872. goodObject
  873. : dataSet
  874. | dictionary
  875. | expression
  876. {
  877. //Remove later to allow sortlist attributes
  878. parser->normalizeExpression($1);
  879. $$.inherit($1);
  880. }
  881. | dataRow
  882. | recordDef
  883. | service
  884. | action
  885. | transformDef
  886. | transform
  887. | complexType
  888. | macro
  889. | embedBody
  890. | eventObject
  891. | compoundAttribute
  892. | abstractModule
  893. | goodTypeObject optFieldAttrs
  894. {
  895. Owned<ITypeInfo> type = $1.getType();
  896. HqlExprArray attrs;
  897. $2.unwindCommaList(attrs);
  898. $$.setExpr(createValue(no_typedef, type.getClear(), attrs), $1);
  899. }
  900. | enumDef
  901. | enumTypeId
  902. | setOfDatasets
  903. | anyFunction
  904. | fieldSelectedFromRecord
  905. {
  906. OwnedHqlExpr value = $1.getExpr();
  907. $$.setExpr(createValue(no_indirect, value->getType(), LINK(value)), $1);
  908. }
  909. | __SEQUENCE__
  910. {
  911. //NB: Undocumented experimental feature
  912. //This is only allowed as an object, rather than a sequence so we can correctly check whether the containing
  913. //attribute (if any) is parametered, and add the implicit parameter there
  914. $$.setExpr(parser->createScopedSequenceExpr(), $1);
  915. }
  916. | DEFINE goodObject
  917. {
  918. //Ugly internal unsupported syntax for defining an out of line function
  919. //Needs a lot more work.
  920. OwnedHqlExpr value = $2.getExpr();
  921. $$.setExpr(parser->convertToOutOfLineFunction($2.pos, value), $1);
  922. }
  923. ;
  924. goodTypeObject
  925. : setType
  926. | simpleType
  927. | alienTypeInstance
  928. | userTypedefType
  929. | RULE TYPE '(' recordDef ')'
  930. {
  931. OwnedHqlExpr record = $4.getExpr();
  932. $$.setType(makeRuleType(record->getType()));
  933. $$.setPosition($1);
  934. }
  935. | explicitDatasetType
  936. | explicitDictionaryType
  937. ;
  938. badObject
  939. : error {
  940. parser->processError(false);
  941. $$.setExpr(createConstant((__int64) 0), $1);
  942. }
  943. ;
  944. macro
  945. : MACRO {
  946. Owned<IFileContents> contents = $1.getContents();
  947. IHqlExpression* expr = createUnknown(no_macro, makeBoolType(), macroAtom, LINK(contents));
  948. #if defined(TRACE_MACRO)
  949. PrintLog("MACRO>> verify: macro definition at %d:%d\n",yylval.startLine, yylval.startColumn);
  950. #endif
  951. //Use a named symbol to associate a line number/column
  952. expr = createSymbol(macroId, NULL, expr, NULL,
  953. false, false, (object_type)0,
  954. NULL,
  955. yylval.pos.lineno, yylval.pos.column, 0, 0, 0);
  956. $$.setExpr(expr, $1);
  957. }
  958. | COMPLEX_MACRO {
  959. Owned<IFileContents> contents = $1.getContents();
  960. IHqlExpression* expr = createUnknown(no_macro, makeVoidType(), macroAtom, LINK(contents));
  961. #if defined(TRACE_MACRO)
  962. PrintLog("MACRO>> verify: macro definition at %d:%d\n",yylval.startLine, yylval.startColumn);
  963. #endif
  964. //Use a named symbol to associate a line number/column
  965. expr = createSymbol(macroId, NULL, expr, NULL,
  966. false, false, (object_type)0,
  967. NULL,
  968. yylval.pos.lineno, yylval.pos.column, 0, 0, 0);
  969. $$.setExpr(expr, $1);
  970. }
  971. ;
  972. embedBody
  973. : CPPBODY {
  974. OwnedHqlExpr embeddedCppText = $1.getExpr();
  975. $$.setExpr(parser->processEmbedBody($1, embeddedCppText, NULL, NULL), $1);
  976. }
  977. | embedPrefix CPPBODY
  978. {
  979. OwnedHqlExpr language = $1.getExpr();
  980. OwnedHqlExpr embedText = $2.getExpr();
  981. if (language->getOperator()==no_comma)
  982. $$.setExpr(parser->processEmbedBody($2, embedText, language->queryChild(0), language->queryChild(1)), $1);
  983. else
  984. $$.setExpr(parser->processEmbedBody($2, embedText, language, NULL), $1);
  985. }
  986. | EMBED '(' abstractModule ',' expression ')'
  987. {
  988. parser->normalizeExpression($5, type_stringorunicode, true);
  989. OwnedHqlExpr language = $3.getExpr();
  990. OwnedHqlExpr embedText = $5.getExpr();
  991. $$.setExpr(parser->processEmbedBody($5, embedText, language, NULL), $1);
  992. }
  993. | IMPORT '(' abstractModule ',' expression attribs ')'
  994. {
  995. parser->normalizeExpression($5, type_stringorunicode, true);
  996. OwnedHqlExpr language = $3.getExpr();
  997. OwnedHqlExpr funcname = $5.getExpr();
  998. OwnedHqlExpr attribs = createComma(createAttribute(importAtom), $6.getExpr());
  999. $$.setExpr(parser->processEmbedBody($6, funcname, language, attribs), $1);
  1000. }
  1001. ;
  1002. embedPrefix
  1003. : EMBED '(' abstractModule attribs ')'
  1004. {
  1005. parser->getLexer()->enterEmbeddedMode();
  1006. $$.setExpr(createComma($3.getExpr(), $4.getExpr()), $1);
  1007. }
  1008. ;
  1009. compoundAttribute
  1010. : startCompoundAttribute optDefinitions returnAction ';' END
  1011. {
  1012. $$.setExpr(parser->processCompoundFunction($3, false), $3);
  1013. }
  1014. ;
  1015. startCompoundAttribute
  1016. : FUNCTION
  1017. {
  1018. parser->enterScope(false);
  1019. parser->enterCompoundObject();
  1020. $$.clear();
  1021. }
  1022. ;
  1023. returnAction
  1024. : RETURN goodObject
  1025. {
  1026. $$.setExpr($2.getExpr(), $2);
  1027. }
  1028. ;
  1029. compoundModule
  1030. : startCompoundModule moduleBase moduleDefinitions END
  1031. {
  1032. $$.setExpr(parser->processModuleDefinition($1), $1);
  1033. }
  1034. | PROJECT '(' abstractModule ',' abstractModule scopeProjectOpts ')'
  1035. {
  1036. OwnedHqlExpr flags = $6.getExpr();
  1037. IHqlExpression *expr = parser->implementInterfaceFromModule($3, $5, flags);
  1038. $$.setExpr(expr, $1);
  1039. }
  1040. ;
  1041. startCompoundModule
  1042. : MODULE
  1043. {
  1044. parser->enterVirtualScope();
  1045. parser->enterCompoundObject();
  1046. $$.setPosition($1);
  1047. }
  1048. | INTERFACE
  1049. {
  1050. parser->enterVirtualScope();
  1051. parser->enterCompoundObject();
  1052. OwnedHqlExpr attr = createAttribute(interfaceAtom);
  1053. parser->appendToActiveScope(attr);
  1054. $$.setPosition($1);
  1055. }
  1056. ;
  1057. moduleDefinitions
  1058. :
  1059. | moduleDefinitions moduleDefinition
  1060. ;
  1061. moduleBase
  1062. : '(' abstractModuleList ')' moduleOptions
  1063. | moduleOptions
  1064. ;
  1065. moduleOptions
  1066. : %prec LOWEST_PRECEDENCE // Ensure that '(' gets shifted instead of causing a s/r error
  1067. | moduleOptions ',' moduleOption
  1068. {
  1069. OwnedHqlExpr expr = $3.getExpr();
  1070. if (expr)
  1071. parser->appendToActiveScope(expr);
  1072. $$.clear();
  1073. $$.setPosition($3);
  1074. }
  1075. ;
  1076. moduleOption
  1077. : __NOSTREAMING__
  1078. {
  1079. //Only for internal testing...
  1080. $$.setExpr(createAttribute(_noStreaming_Atom), $1);
  1081. }
  1082. | INTERFACE
  1083. {
  1084. $$.setExpr(createAttribute(interfaceAtom), $1);
  1085. }
  1086. | VIRTUAL
  1087. {
  1088. $$.setExpr(createAttribute(virtualAtom), $1);
  1089. }
  1090. | FORWARD
  1091. {
  1092. parser->processForwardModuleDefinition($1);
  1093. $$.setExpr(NULL, $1);
  1094. }
  1095. | LIBRARY '(' scopeFunction ')'
  1096. {
  1097. $$.setExpr(createExprAttribute(libraryAtom, $3.getExpr()), $1);
  1098. }
  1099. ;
  1100. abstractModuleList
  1101. : abstractModuleItem
  1102. | abstractModuleList ',' abstractModuleItem
  1103. ;
  1104. abstractModuleItem
  1105. : abstractModule
  1106. {
  1107. OwnedHqlExpr expr = $1.getExpr();
  1108. if (parser->checkValidBaseModule($1, expr))
  1109. parser->appendToActiveScope(expr);
  1110. $$.clear();
  1111. $$.setPosition($1);
  1112. }
  1113. ;
  1114. //MORE: If complex type could be defined in a non assignment context then TYPE will need to become hard reserved.
  1115. complexType
  1116. : startTYPE definitions END
  1117. {
  1118. $$.setExpr(parser->processAlienType($3),$1);
  1119. }
  1120. | startTYPE END {
  1121. parser->reportError(ERR_USRTYPE_EMPTYDEF,$1,"Empty user TYPE definition");
  1122. $$.setExpr(parser->processAlienType($2),$1);
  1123. }
  1124. ;
  1125. startTYPE
  1126. : TYPE {
  1127. parser->beginAlienType($1);
  1128. $$.clear();
  1129. $$.setPosition($1);
  1130. }
  1131. ;
  1132. defineid
  1133. : UNKNOWN_ID {
  1134. parser->beginDefineId($1.getId(), NULL);
  1135. $$.setType(NULL);
  1136. $$.setPosition($1);
  1137. }
  1138. | SCOPE_ID {
  1139. parser->beginDefineId(parser->getNameFromExpr($1), NULL);
  1140. $$.setType(NULL);
  1141. $$.setPosition($1);
  1142. }
  1143. | recordDef {
  1144. parser->beginDefineId(parser->getNameFromExpr($1), NULL);
  1145. $$.setType(NULL);
  1146. $$.setPosition($1);
  1147. }
  1148. | TRANSFORM_ID {
  1149. parser->beginDefineId(parser->getNameFromExpr($1), NULL);
  1150. $$.setType(NULL);
  1151. $$.setPosition($1);
  1152. }
  1153. | TYPE_ID {
  1154. parser->beginDefineId(parser->getNameFromExpr($1), NULL);
  1155. $$.setType(NULL);
  1156. $$.setPosition($1);
  1157. }
  1158. | defineType knownOrUnknownId
  1159. {
  1160. Owned<ITypeInfo> type = $1.getType();
  1161. if (type->getTypeCode() == type_alien)
  1162. type.set(type->queryPromotedType());
  1163. parser->beginDefineId($2.getId(), type);
  1164. $$.setType(type.getClear());
  1165. $$.setPosition($1);
  1166. }
  1167. | globalScopedDatasetId knownOrUnknownId
  1168. {
  1169. OwnedHqlExpr ds = $1.getExpr();
  1170. parser->beginDefineId($2.getId(), ds->queryType());
  1171. $$.setType(ds->getType());
  1172. $$.setPosition($1);
  1173. }
  1174. | UNKNOWN_ID UNKNOWN_ID
  1175. {
  1176. parser->reportError(ERR_UNKNOWN_TYPE, $1, "Unknown type '%s'", $1.getId()->str());
  1177. parser->beginDefineId($2.getId(), NULL);
  1178. $$.setType(NULL);
  1179. $$.setPosition($1);
  1180. }
  1181. ;
  1182. knownOrUnknownId
  1183. : UNKNOWN_ID
  1184. | knownId { $$.setId(parser->getNameFromExpr($1)); $$.setPosition($1); }
  1185. | knownFunction1 { $$.setId(parser->getNameFromExpr($1)); $$.setPosition($1); }
  1186. ;
  1187. knownId
  1188. : DATAROW_ID
  1189. | DATASET_ID
  1190. | DICTIONARY_ID
  1191. | VALUE_ID
  1192. | ACTION_ID
  1193. | RECORD_ID
  1194. | ALIEN_ID
  1195. | TYPE_ID
  1196. | TRANSFORM_ID
  1197. | FEATURE_ID
  1198. | SCOPE_ID
  1199. | PATTERN_ID
  1200. | LIST_DATASET_ID
  1201. ;
  1202. knownFunction1
  1203. : DATAROW_FUNCTION
  1204. | DATASET_FUNCTION
  1205. | DICTIONARY_FUNCTION
  1206. | VALUE_FUNCTION
  1207. | ACTION_FUNCTION
  1208. | PATTERN_FUNCTION
  1209. | EVENT_FUNCTION
  1210. | TRANSFORM_FUNCTION
  1211. | LIST_DATASET_FUNCTION
  1212. // Following cause s/r problems
  1213. // | RECORD_FUNCTION
  1214. // | SCOPE_FUNCTION
  1215. ;
  1216. scopeFlag
  1217. : EXPORT { $$.setInt(EXPORT_FLAG); $$.setPosition($1); }
  1218. | SHARED { $$.setInt(SHARED_FLAG); $$.setPosition($1); }
  1219. | LOCAL { $$.setInt(0); $$.setPosition($1); }
  1220. | EXPORT VIRTUAL { $$.setInt(EXPORT_FLAG|VIRTUAL_FLAG); $$.setPosition($1); }
  1221. | SHARED VIRTUAL { $$.setInt(SHARED_FLAG|VIRTUAL_FLAG); $$.setPosition($1); }
  1222. ;
  1223. // scopeflags needs to be explicitly included, rather than using an optScopeFlags production, otherwise you get shift reduce errors - since it is the first item on a line.
  1224. defineidWithOptScope
  1225. : defineid {
  1226. $$.setDefineId(parser->createDefineId(0, $1.getType()));
  1227. $$.setPosition($1);
  1228. }
  1229. | scopeFlag defineid
  1230. {
  1231. $$.setDefineId(parser->createDefineId((int)$1.getInt(), $2.getType()));
  1232. $$.setPosition($1);
  1233. }
  1234. ;
  1235. definePatternIdWithOptScope
  1236. : definePatternId {
  1237. $$.setDefineId(parser->createDefineId(0, $1.getType()));
  1238. $$.setPosition($1);
  1239. }
  1240. | scopeFlag definePatternId
  1241. {
  1242. $$.setDefineId(parser->createDefineId((int)$1.getInt(), $2.getType()));
  1243. $$.setPosition($1);
  1244. }
  1245. ;
  1246. definePatternId
  1247. : TOK_PATTERN knownOrUnknownId
  1248. {
  1249. ITypeInfo *type = makePatternType();
  1250. parser->beginDefineId($2.getId(), type);
  1251. $$.setType(type);
  1252. $$.setPosition($1);
  1253. }
  1254. | RULE knownOrUnknownId
  1255. {
  1256. ITypeInfo *type = makeRuleType(NULL);
  1257. parser->beginDefineId($2.getId(), type);
  1258. $$.setType(type);
  1259. $$.setPosition($1);
  1260. }
  1261. | RULE '(' recordDef ')' knownOrUnknownId
  1262. {
  1263. OwnedHqlExpr record = $3.getExpr();
  1264. ITypeInfo *type = makeRuleType(record->getType());
  1265. parser->beginDefineId($5.getId(), type);
  1266. $$.setType(type);
  1267. $$.setPosition($1);
  1268. }
  1269. | TOKEN knownOrUnknownId
  1270. {
  1271. ITypeInfo *type = makeTokenType();
  1272. parser->beginDefineId($2.getId(), type);
  1273. $$.setType(type);
  1274. $$.setPosition($1);
  1275. }
  1276. | userTypedefPattern knownOrUnknownId
  1277. {
  1278. ITypeInfo *type = $1.getType();
  1279. parser->beginDefineId($2.getId(), type);
  1280. $$.setType(type);
  1281. $$.setPosition($1);
  1282. }
  1283. ;
  1284. optDefinitions
  1285. :
  1286. | optDefinitions definition
  1287. ;
  1288. definitions
  1289. : definition
  1290. | definitions definition
  1291. ;
  1292. attributeDefinition
  1293. : DEFINITIONS_MACRO definition
  1294. | moduleScopeDot DEFINITIONS_MACRO leaveScope definition
  1295. {
  1296. $1.release();
  1297. $$.clear();
  1298. }
  1299. | defineidWithOptScope parmdef ASSIGN object optfailure ';'
  1300. {
  1301. if ($5.queryExpr())
  1302. parser->normalizeExpression($4);
  1303. $$.clear($1);
  1304. parser->defineSymbolProduction($1, $2, $3, &$4, &$5, $6);
  1305. }
  1306. | definePatternIdWithOptScope parmdef featureParameters ASSIGN pattern optfailure ';'
  1307. {
  1308. parser->definePatternSymbolProduction($1, $4, $5, $6, $7);
  1309. $$.clear();
  1310. }
  1311. | defineFeatureIdWithOptScope ';'
  1312. {
  1313. DefineIdSt* defineid = $1.getDefineId();
  1314. IHqlExpression *expr = createValue(no_null, makeFeatureType());
  1315. expr = createValue(no_pat_featuredef, expr->getType(), expr);
  1316. parser->doDefineSymbol(defineid, expr, NULL, $1, $2.pos.position, $2.pos.position, false);
  1317. $$.clear();
  1318. }
  1319. | defineFeatureIdWithOptScope ASSIGN featureDefine ';'
  1320. {
  1321. DefineIdSt* defineid = $1.getDefineId();
  1322. IHqlExpression *expr = $3.getExpr();
  1323. expr = createValue(no_pat_featuredef, expr->getType(), expr);
  1324. parser->doDefineSymbol(defineid, expr, NULL, $1, $2.pos.position, $4.pos.position, false);
  1325. $$.clear();
  1326. }
  1327. ;
  1328. definition
  1329. : simpleDefinition
  1330. | ';' {
  1331. //Extra ';' are ignored, partly to reduce problems with trailing ';' inside macros
  1332. $$.clear();
  1333. }
  1334. ;
  1335. simpleDefinition
  1336. : attributeDefinition
  1337. | query ';' {
  1338. parser->addResult($1.getExpr(), $1);
  1339. $$.clear();
  1340. }
  1341. /* general error */
  1342. | error ';' {
  1343. yyerrok;
  1344. parser->processError(true);
  1345. $$.clear();
  1346. }
  1347. | importSection
  1348. | metaCommandWithNoSemicolon simpleDefinition
  1349. ;
  1350. metaCommandWithNoSemicolon
  1351. : setMetaCommand
  1352. {
  1353. //These are really treated like actions now, this is here for backward compatibility
  1354. parser->reportWarning(ERR_DEPRECATED, $1.pos, "#command with no trailing semicolon is deprecated");
  1355. parser->addResult($1.getExpr(), $1);
  1356. $$.clear();
  1357. }
  1358. ;
  1359. moduleDefinition
  1360. : defineidWithOptScope parmdef ';'
  1361. {
  1362. parser->defineSymbolProduction($1, $2, $3, NULL, NULL, $3);
  1363. $$.clear();
  1364. $$.setPosition($1);
  1365. }
  1366. | definition
  1367. ;
  1368. setMetaCommand
  1369. : HASH_OPTION '(' expression ',' expression ')'
  1370. {
  1371. parser->normalizeExpression($3, type_string, true);
  1372. parser->normalizeExpression($5, type_any, true);
  1373. $$.setExpr(createValue(no_setmeta, makeVoidType(), createAttribute(debugAtom), $3.getExpr(), $5.getExpr()), $1);
  1374. }
  1375. | HASH_WORKUNIT '(' expression ',' expression ')'
  1376. {
  1377. parser->normalizeExpression($3, type_string, true);
  1378. parser->normalizeExpression($5, type_any, true);
  1379. $$.setExpr(createValue(no_setmeta, makeVoidType(), createAttribute(workunitAtom), $3.getExpr(), $5.getExpr()), $1);
  1380. }
  1381. | HASH_STORED '(' expression ',' hashStoredValue ')'
  1382. {
  1383. parser->normalizeStoredNameExpression($3);
  1384. $$.setExpr(createValue(no_setmeta, makeVoidType(), createAttribute(storedAtom), $3.getExpr(), $5.getExpr()), $1);
  1385. }
  1386. | HASH_CONSTANT '(' expression ',' hashStoredValue ')'
  1387. {
  1388. parser->normalizeStoredNameExpression($3);
  1389. $$.setExpr(createValue(no_setmeta, makeVoidType(), createAttribute(constAtom), $3.getExpr(), $5.getExpr()), $1);
  1390. }
  1391. | HASH_LINK '(' expression ')'
  1392. {
  1393. parser->normalizeExpression($3, type_string, true);
  1394. $$.setExpr(createValue(no_setmeta, makeVoidType(), createAttribute(linkAtom), $3.getExpr()), $1);
  1395. }
  1396. | HASH_ONWARNING '(' expression ',' warningAction ')'
  1397. {
  1398. parser->normalizeExpression($3, type_int, false);
  1399. $$.setExpr(createValue(no_setmeta, makeVoidType(), createAttribute(onWarningAtom), $3.getExpr(), $5.getExpr()), $1);
  1400. }
  1401. ;
  1402. hashStoredValue
  1403. : expression
  1404. {
  1405. parser->normalizeExpression($1, type_any, false);
  1406. $$.inherit($1);
  1407. }
  1408. | dataSet
  1409. | dataRow
  1410. ;
  1411. optfailure
  1412. : ':' failclause
  1413. {
  1414. $$.setExpr($2.getExpr(), $1);
  1415. }
  1416. | { $$.setNullExpr(); $$.clearPosition(); }
  1417. ;
  1418. failclause
  1419. : failure
  1420. | failclause ',' failure
  1421. {
  1422. IHqlExpression * previousWorkflow = $1.getExpr();
  1423. IHqlExpression * newWorkflow = $3.getExpr();
  1424. parser->checkWorkflowMultiples(previousWorkflow, newWorkflow, $3);
  1425. $$.setExpr(createComma(previousWorkflow, newWorkflow), $1);
  1426. }
  1427. ;
  1428. failure
  1429. : FAILURE '(' action ')'
  1430. {
  1431. $$.setExpr(createValue(no_failure, $3.getExpr(), NULL), $1);
  1432. }
  1433. | SUCCESS '(' action ')'
  1434. {
  1435. $$.setExpr(createValue(no_success, $3.getExpr(), NULL), $1);
  1436. }
  1437. | RECOVERY '(' action ')'
  1438. {
  1439. $$.setExpr(createValue(no_recovery, $3.getExpr(), createConstant(1)), $1);
  1440. }
  1441. | RECOVERY '(' action ',' expression ')'
  1442. {
  1443. parser->normalizeExpression($5, type_int, true);
  1444. $$.setExpr(createValue(no_recovery, $3.getExpr(), $5.getExpr()), $1);
  1445. }
  1446. | WHEN '(' event ')'
  1447. {
  1448. parser->checkConstantEvent($3);
  1449. $$.setExpr(createValue(no_when, $3.getExpr()), $1);
  1450. }
  1451. | WHEN '(' event ',' COUNT '(' expression ')' ')'
  1452. {
  1453. parser->checkConstantEvent($3);
  1454. parser->normalizeExpression($7, type_int, true);
  1455. $$.setExpr(createValue(no_when, $3.getExpr(), $7.getExpr()), $1);
  1456. }
  1457. | PRIORITY '(' expression ')'
  1458. {
  1459. parser->normalizeExpression($3, type_int, true);
  1460. $$.setExpr(createValue(no_priority, $3.getExpr()), $1);
  1461. }
  1462. | PERSIST '(' expression ')'
  1463. {
  1464. parser->normalizeExpression($3, type_string, true);
  1465. $$.setExpr(createValueF(no_persist, makeVoidType(), $3.getExpr(), NULL), $1);
  1466. }
  1467. | PERSIST '(' expression ',' persistOpts ')'
  1468. {
  1469. parser->normalizeExpression($3, type_string, true);
  1470. $$.setExpr(createValueF(no_persist, makeVoidType(), $3.getExpr(), $5.getExpr(), NULL), $1);
  1471. }
  1472. | PERSIST '(' expression ',' expression optPersistOpts ')'
  1473. {
  1474. parser->normalizeExpression($3, type_string, true);
  1475. parser->normalizeExpression($5, type_string, true);
  1476. $$.setExpr(createValueF(no_persist, makeVoidType(), $3.getExpr(), $5.getExpr(), $6.getExpr(), NULL), $1);
  1477. }
  1478. | STORED '(' expression optFewMany ')'
  1479. {
  1480. parser->normalizeStoredNameExpression($3);
  1481. $$.setExpr(createValue(no_stored, makeVoidType(), $3.getExpr(), $4.getExpr()), $1);
  1482. }
  1483. | CHECKPOINT '(' constExpression ')'
  1484. {
  1485. parser->normalizeStoredNameExpression($3);
  1486. $$.setExpr(createValue(no_checkpoint, makeVoidType(), $3.getExpr()), $1);
  1487. }
  1488. | GLOBAL
  1489. {
  1490. $$.setExpr(createValue(no_global), $1);
  1491. }
  1492. | GLOBAL '(' fewMany ')'
  1493. {
  1494. $$.setExpr(createValue(no_global, $3.getExpr()), $1);
  1495. }
  1496. | GLOBAL '(' expression optFewMany ')'
  1497. {
  1498. parser->normalizeExpression($3, type_string, false);
  1499. $$.setExpr(createValue(no_global, $3.getExpr(), $4.getExpr()), $1);
  1500. }
  1501. | INDEPENDENT
  1502. {
  1503. $$.setExpr(createValue(no_independent), $1);
  1504. }
  1505. | INDEPENDENT '(' fewMany ')'
  1506. {
  1507. $$.setExpr(createValue(no_independent, $3.getExpr()), $1);
  1508. }
  1509. | INDEPENDENT '(' expression optFewMany ')'
  1510. {
  1511. $$.setExpr(createValue(no_independent, $3.getExpr(), $4.getExpr()), $1);
  1512. }
  1513. | DEFINE '(' stringConstExpr ')'
  1514. {
  1515. $$.setExpr(createAttribute(defineAtom, $3.getExpr()), $1);
  1516. }
  1517. | DEPRECATED
  1518. {
  1519. $$.setExpr(createAttribute(deprecatedAtom), $1);
  1520. }
  1521. | DEPRECATED '(' stringConstExpr ')'
  1522. {
  1523. $$.setExpr(createAttribute(deprecatedAtom, $3.getExpr()), $1);
  1524. }
  1525. | SECTION '(' constExpression sectionArguments ')'
  1526. {
  1527. parser->normalizeExpression($3, type_string, false);
  1528. HqlExprArray args;
  1529. args.append(*$3.getExpr());
  1530. $4.unwindCommaList(args);
  1531. $$.setExpr(createAttribute(sectionAtom, args), $1);
  1532. }
  1533. | ONWARNING '(' constExpression ',' warningAction ')'
  1534. {
  1535. parser->normalizeExpression($3, type_int, false);
  1536. $$.setExpr(createAttribute(onWarningAtom, $3.getExpr(), $5.getExpr()), $1);
  1537. }
  1538. | LABELED '(' expression ')'
  1539. {
  1540. parser->normalizeStoredNameExpression($3);
  1541. $$.setExpr(createAttribute(labeledAtom, $3.getExpr()), $1);
  1542. }
  1543. | ONCE
  1544. {
  1545. $$.setExpr(createValue(no_once, makeVoidType()), $1);
  1546. }
  1547. | ONCE '(' fewMany ')'
  1548. {
  1549. $$.setExpr(createValue(no_once, $3.getExpr()), $1);
  1550. }
  1551. ;
  1552. warningAction
  1553. : TOK_LOG { $$.setExpr(createAttribute(logAtom), $1); }
  1554. | TOK_IGNORE { $$.setExpr(createAttribute(ignoreAtom), $1); }
  1555. | TOK_WARNING { $$.setExpr(createAttribute(warningAtom), $1); }
  1556. | TOK_ERROR { $$.setExpr(createAttribute(errorAtom), $1); }
  1557. | FAIL { $$.setExpr(createAttribute(failAtom), $1); }
  1558. ;
  1559. optPersistOpts
  1560. : { $$.setNullExpr(); }
  1561. | ',' persistOpts {
  1562. $$.setExpr($2.getExpr(), $2);
  1563. }
  1564. ;
  1565. persistOpts
  1566. : persistOpt
  1567. | persistOpts ',' persistOpt
  1568. {
  1569. $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1);
  1570. }
  1571. ;
  1572. persistOpt
  1573. : fewMany
  1574. | expireAttr
  1575. | clusterAttr
  1576. | SINGLE { $$.setExpr(createAttribute(singleAtom), $1); }
  1577. | MULTIPLE { $$.setExpr(createExprAttribute(multipleAtom), $1); }
  1578. | MULTIPLE '(' expression ')'
  1579. {
  1580. parser->normalizeExpression($3, type_int, true);
  1581. $$.setExpr(createExprAttribute(multipleAtom, $3.getExpr()), $1);
  1582. }
  1583. ;
  1584. globalOpts
  1585. : { $$.setNullExpr(); }
  1586. | ',' globalOpts2 { $$.inherit($2); }
  1587. ;
  1588. globalOpts2
  1589. : globalOpt
  1590. | globalOpts2 ',' globalOpt
  1591. {
  1592. $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1);
  1593. }
  1594. ;
  1595. globalOpt
  1596. : FEW { $$.setExpr(createAttribute(fewAtom), $1); }
  1597. | MANY { $$.setExpr(createAttribute(manyAtom), $1); }
  1598. | OPT { $$.setExpr(createAttribute(optAtom), $1); }
  1599. ;
  1600. optFewMany
  1601. : { $$.setNullExpr(); }
  1602. | ',' FEW { $$.setExpr(createAttribute(fewAtom), $1); }
  1603. | ',' MANY { $$.setExpr(createAttribute(manyAtom), $1); }
  1604. ;
  1605. fewMany
  1606. : FEW { $$.setExpr(createAttribute(fewAtom), $1); }
  1607. | MANY { $$.setExpr(createAttribute(manyAtom), $1); }
  1608. ;
  1609. optKeyedDistributeAttrs
  1610. : { $$.setNullExpr(); }
  1611. | ',' keyedDistributeAttribute optKeyedDistributeAttrs
  1612. {
  1613. $$.setExpr(createComma($2.getExpr(), $3.getExpr()), $2);
  1614. }
  1615. ;
  1616. keyedDistributeAttribute
  1617. : FIRST { $$.setExpr(createAttribute(firstAtom), $1); } // leading components of the key
  1618. | hintAttribute
  1619. ;
  1620. optDistributeAttrs
  1621. : { $$.setNullExpr(); }
  1622. | ',' distributeAttribute optDistributeAttrs
  1623. {
  1624. $$.setExpr(createComma($2.getExpr(), $3.getExpr()), $2);
  1625. }
  1626. ;
  1627. distributeAttribute
  1628. : PULLED
  1629. {
  1630. $$.setExpr(createAttribute(pulledAtom), $1);
  1631. }
  1632. | hintAttribute
  1633. | MERGE_ATTR '(' beginList sortList ')'
  1634. {
  1635. HqlExprArray sortItems;
  1636. parser->endList(sortItems);
  1637. IHqlExpression * sortlist = parser->processSortList($4, no_sortlist, NULL, sortItems, NULL, NULL);
  1638. $$.setExpr(createExprAttribute(mergeAtom, sortlist), $1);
  1639. }
  1640. ;
  1641. transformDef
  1642. : startTransform transformOptions transformations END
  1643. {
  1644. $$.setExpr(parser->closeTransform($4), $1);
  1645. parser->leaveCompoundObject();
  1646. }
  1647. | startTransform transformOptions END
  1648. {
  1649. parser->reportError(ERR_TRANSFORM_EMPTYDEF,$1,"Empty transform definition");
  1650. $$.setExpr(parser->closeTransform($3), $1);
  1651. parser->leaveCompoundObject();
  1652. }
  1653. ;
  1654. transform
  1655. : TRANSFORM_ID
  1656. | moduleScopeDot TRANSFORM_ID leaveScope
  1657. {
  1658. $1.release();
  1659. $$.setExpr($2.getExpr(), $1);
  1660. }
  1661. | transformFunction '('
  1662. {
  1663. parser->beginFunctionCall($1);
  1664. }
  1665. actualParameters ')'
  1666. {
  1667. $$.setExpr(parser->bindParameters($1, $4.getExpr()), $1);
  1668. }
  1669. | startInlineTransform transformOptions semiComma transformations ')'
  1670. {
  1671. $$.setExpr(parser->closeTransform($4), $1);
  1672. parser->leaveCompoundObject();
  1673. }
  1674. | TRANSFORM '(' dataRow ')'
  1675. {
  1676. OwnedHqlExpr value = $3.getExpr();
  1677. IHqlExpression * record = value->queryRecord();
  1678. $$.setExpr(parser->createDefaultAssignTransform(record, value, $1), $1);
  1679. }
  1680. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN transform ';' endInlineFunctionToken
  1681. {
  1682. Owned<ITypeInfo> retType = $1.getType();
  1683. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  1684. }
  1685. ;
  1686. startInlineTransform
  1687. : TRANSFORM '(' recordDef
  1688. {
  1689. OwnedHqlExpr record = $3.getExpr();
  1690. Owned<ITypeInfo> type = createRecordType(record);
  1691. parser->openTransform(type);
  1692. $$.clear($1);
  1693. }
  1694. ;
  1695. opt_join_transform_flags
  1696. : ',' transform optJoinFlags
  1697. {
  1698. IHqlExpression* flags = $3.getExpr();
  1699. IHqlExpression* trans_expr = $2.getExpr();
  1700. // some fatal error happened
  1701. if (!trans_expr || !trans_expr->isTransform())
  1702. {
  1703. ::Release(trans_expr);
  1704. ::Release(flags);
  1705. $$.setNullExpr();
  1706. }
  1707. else
  1708. $$.setExpr(createComma(trans_expr, flags));
  1709. $$.setPosition($2);
  1710. }
  1711. | optJoinFlags
  1712. ;
  1713. startTransform
  1714. : TRANSFORM {
  1715. parser->processStartTransform($1);
  1716. $$.clear($1);
  1717. }
  1718. ;
  1719. transformOptions
  1720. :
  1721. | transformOptions semiComma transformOption
  1722. {
  1723. parser->appendTransformOption($3.getExpr());
  1724. $$.setPosition($1);
  1725. }
  1726. ;
  1727. transformOption
  1728. : SKIP '(' booleanExpr ')'
  1729. {
  1730. $$.setExpr(createValue(no_skip, makeVoidType(), $3.getExpr()), $1);
  1731. }
  1732. ;
  1733. transformations
  1734. : transformation
  1735. | transformations semiComma transformation
  1736. | transformations semiComma
  1737. {
  1738. $$.setPosition($1);
  1739. }
  1740. ;
  1741. transformation
  1742. : transformPrefix transformation1
  1743. {
  1744. $$.setPosition($2);
  1745. }
  1746. ;
  1747. transformPrefix
  1748. :
  1749. | transformPrefixList
  1750. ;
  1751. transformPrefixList
  1752. : transformPrefixItem
  1753. | transformPrefixList transformPrefixItem
  1754. | transformPrefixList ';'
  1755. ;
  1756. transformPrefixItem
  1757. : DEFINITIONS_MACRO
  1758. | moduleScopeDot DEFINITIONS_MACRO leaveScope
  1759. {
  1760. $1.release();
  1761. $$.clear();
  1762. }
  1763. | defineTransformObject
  1764. | conditionalAttributeAssignment ';'
  1765. | importSection
  1766. ;
  1767. conditionalAttributeAssignment // not a conditional field assignment.....
  1768. : IF expression THEN conditionalAssignments conditionalAssignmentElseClause
  1769. {
  1770. //Allow IF integer to ease SAS translation
  1771. parser->normalizeExpression($2);
  1772. parser->ensureBoolean($2);
  1773. OwnedHqlExpr cond = $2.getExpr();
  1774. OwnedHqlExpr trueScope = $4.getExpr();
  1775. OwnedHqlExpr falseScope = $5.getExpr();
  1776. parser->processIfScope($1,cond, trueScope, falseScope);
  1777. $$.clear();
  1778. }
  1779. ;
  1780. conditionalAssignments
  1781. : beginConditionalScope transformPrefix
  1782. {
  1783. $$.setExpr(queryExpression(parser->closeLeaveScope($2)), $2);
  1784. }
  1785. ;
  1786. beginConditionalScope
  1787. : { parser->enterScope(false); $$.clear(); }
  1788. ;
  1789. conditionalAssignmentElseClause
  1790. : END { $$.setNullExpr(); }
  1791. | ELSE conditionalAssignments END
  1792. { $$.setExpr($2.getExpr(), $2); }
  1793. | ELSEIF expression THEN conditionalAssignments conditionalAssignmentElseClause
  1794. {
  1795. parser->normalizeExpression($2);
  1796. parser->ensureBoolean($2);
  1797. //normalizeExpression($2, type_boolean, false);
  1798. OwnedHqlExpr map = createValue(no_mapto, $2.getExpr(), $4.getExpr());
  1799. $$.setExpr(createComma(map.getClear(), $5.getExpr()), $1);
  1800. }
  1801. ;
  1802. defineTransformObject
  1803. : beginDefineTransformObject parmdef ASSIGN object optfailure ';'
  1804. {
  1805. parser->defineSymbolProduction($1, $2, $3, &$4, &$5, $6);
  1806. $$.clear($1);
  1807. parser->restoreTypeFromActiveTransform();
  1808. }
  1809. ;
  1810. beginDefineTransformObject
  1811. : defineid
  1812. {
  1813. $$.setDefineId(parser->createDefineId(0, $1.getType()));
  1814. $$.setPosition($1);
  1815. }
  1816. ;
  1817. transformation1
  1818. : transformDst ASSIGN expression
  1819. {
  1820. parser->normalizeExpression($3);
  1821. ITypeInfo * type = $1.queryExprType();
  1822. if (!type || type->getTypeCode() != type_set)
  1823. {
  1824. IHqlExpression * arg = $3.queryExpr();
  1825. if ((arg->getOperator() == no_list) && (arg->numChildren() == 0))
  1826. {
  1827. $3.release().setExpr(createValue(no_null));
  1828. }
  1829. }
  1830. parser->addAssignment($1, $3);
  1831. $$.clear($1);
  1832. }
  1833. | transformDst ASSIGN dataRow
  1834. {
  1835. IHqlExpression * value = $3.queryExpr();
  1836. if (value)
  1837. {
  1838. IHqlExpression * target = $1.queryExpr();
  1839. if (target->isDataset())
  1840. {
  1841. value = createDatasetFromRow(LINK(value));
  1842. $3.release();
  1843. $3.setExpr(value);
  1844. parser->addAssignment($1, $3);
  1845. }
  1846. else
  1847. parser->addAssignall($1.getExpr(), $3.getExpr(), $1);
  1848. }
  1849. else /* this happens when an error C2022 occurred */
  1850. $1.release();
  1851. $$.clear($1);
  1852. }
  1853. | transformDst ASSIGN dataSet
  1854. {
  1855. parser->addAssignment($1, $3);
  1856. $$.clear($1);
  1857. }
  1858. | transformDst ASSIGN dictionary
  1859. {
  1860. parser->addAssignment($1, $3);
  1861. $$.clear($1);
  1862. }
  1863. | transformDst ASSIGN error ';'
  1864. {
  1865. $1.release();
  1866. $$.clear();
  1867. }
  1868. | assertAction {
  1869. parser->appendTransformOption($1.getExpr());
  1870. $$.clear($1);
  1871. }
  1872. ;
  1873. //----------------------------------------------------------------------------
  1874. transformDst
  1875. : transformDstRecord leaveScope
  1876. {
  1877. $$.setExpr($1.getExpr(), $1);
  1878. }
  1879. | transformDstRecord '.' transformDstField
  1880. {
  1881. OwnedHqlExpr lhs = $1.getExpr();
  1882. if (lhs->isDataset())
  1883. parser->reportError(ERR_ASSIGN_MEMBER_DATASET, $1, "Cannot directly assign to field %s within a child dataset", $3.queryExpr()->queryName()->str());
  1884. $$.setExpr(parser->createSelect(lhs.getClear(), $3.getExpr(), $3), $1);
  1885. }
  1886. ;
  1887. transformDstRecord
  1888. : startSelf
  1889. | transformDstRecord '.' transformDstSelect
  1890. {
  1891. OwnedHqlExpr lhs = $1.getExpr();
  1892. if (lhs->isDataset())
  1893. parser->reportError(ERR_ASSIGN_MEMBER_DATASET, $1, "Cannot directly assign to field %s within a child dataset", $3.queryExpr()->queryName()->str());
  1894. $$.setExpr(parser->createSelect(lhs.getClear(), $3.getExpr(), $3), $1);
  1895. }
  1896. | transformDstRecord '.' transformDstSelect leaveScope '[' expression ']'
  1897. {
  1898. parser->normalizeExpression($6, type_int, false);
  1899. parser->reportError(ERR_ASSIGN_MEMBER_DATASET, $1, "Cannot assign to individual elements of a list or dataset");
  1900. parser->setDotScope($3.queryExpr());
  1901. // Of course this is not the way arrays are going to work,
  1902. // need to adjust to whatever is necessary when we implement it - YMA.
  1903. $$.setExpr(parser->createSelect($1.getExpr(), $3.getExpr(), $3), $1);
  1904. $6.release();
  1905. }
  1906. ;
  1907. startSelf
  1908. : SELF {
  1909. OwnedHqlExpr self = parser->getSelfScope();
  1910. if (!self)
  1911. self.set(queryNullRecord());
  1912. parser->setDotScope(self);
  1913. $$.setExpr(getSelf(self), $1);
  1914. }
  1915. ;
  1916. transformDstSelect
  1917. : DATAROW_ID
  1918. {
  1919. OwnedHqlExpr scope = $1.getExpr();
  1920. parser->setDotScope(scope);
  1921. $$.setExpr(scope.getClear(), $1);
  1922. }
  1923. | RECORD_ID
  1924. {
  1925. OwnedHqlExpr scope = $1.getExpr();
  1926. parser->setDotScope(scope);
  1927. $$.setExpr(scope.getClear(), $1);
  1928. }
  1929. | DATASET_ID
  1930. {
  1931. OwnedHqlExpr scope = $1.getExpr();
  1932. parser->setDotScope(scope);
  1933. $$.setExpr(scope.getClear(), $1);
  1934. }
  1935. | DICTIONARY_ID
  1936. {
  1937. OwnedHqlExpr scope = $1.getExpr();
  1938. parser->setDotScope(scope);
  1939. $$.setExpr(scope.getClear(), $1);
  1940. }
  1941. ;
  1942. transformDstField
  1943. : VALUE_ID leaveScope
  1944. | VALUE_ID leaveScope '[' expression ']'
  1945. {
  1946. parser->normalizeExpression($4, type_int, false);
  1947. parser->reportError(ERR_ASSIGN_MEMBER_DATASET, $1, "Cannot assign to individual elements of a list or dataset");
  1948. $$.setExpr($1.getExpr(), $1);
  1949. $4.release();
  1950. }
  1951. | startPointerToMember leaveScope VALUE_ID_REF endPointerToMember
  1952. {
  1953. OwnedHqlExpr expr = $3.getExpr();
  1954. $$.setExpr(createValue(no_indirect, expr->getType(), LINK(expr)), $1);
  1955. }
  1956. ;
  1957. //----------------------------------------------------------------------------
  1958. dotScope
  1959. : dataSet '.' {
  1960. IHqlExpression *e = $1.getExpr();
  1961. parser->setDotScope(e);
  1962. $$.setExpr(e, $1);
  1963. }
  1964. | SELF '.' {
  1965. $$.setExpr(parser->getSelfDotExpr($1), $1);
  1966. }
  1967. | dataRow '.' {
  1968. IHqlExpression *e = $1.getExpr();
  1969. parser->setDotScope(e);
  1970. $$.setExpr(e, $1);
  1971. }
  1972. | enumTypeId '.' {
  1973. IHqlExpression *e = $1.getExpr();
  1974. parser->setDotScope(e);
  1975. $$.setExpr(e, $1);
  1976. }
  1977. ;
  1978. recordScope
  1979. : globalRecordId '.'
  1980. {
  1981. IHqlExpression *e = $1.getExpr();
  1982. parser->setDotScope(e);
  1983. $$.setExpr(e, $1);
  1984. }
  1985. | recordScope DATAROW_ID '.'
  1986. {
  1987. IHqlExpression * scope = $1.getExpr();
  1988. IHqlExpression * e = $2.getExpr();
  1989. IHqlExpression * select = createSelectExpr(scope, e);
  1990. parser->setDotScope(select);
  1991. $$.setExpr(select, $1);
  1992. }
  1993. | recordScope DATASET_ID '.'
  1994. {
  1995. IHqlExpression * scope = $1.getExpr();
  1996. IHqlExpression * e = $2.getExpr();
  1997. IHqlExpression * select = createSelectExpr(scope, e);
  1998. parser->setDotScope(select);
  1999. $$.setExpr(select, $1);
  2000. }
  2001. ;
  2002. simpleRecord
  2003. : recordScope DATAROW_ID leaveScope
  2004. {
  2005. OwnedHqlExpr e = $2.getExpr();
  2006. $1.release();
  2007. $$.setExpr(LINK(queryOriginalRecord(e)), $1);
  2008. }
  2009. | globalRecordId
  2010. ;
  2011. globalRecordId
  2012. : RECORD_ID
  2013. | moduleScopeDot RECORD_ID leaveScope
  2014. {
  2015. $1.release();
  2016. $$.setExpr($2.getExpr(), $1);
  2017. }
  2018. | recordFunction '('
  2019. {
  2020. parser->beginFunctionCall($1);
  2021. }
  2022. actualParameters ')'
  2023. {
  2024. $$.setExpr(parser->bindParameters($1, $4.getExpr()), $1);
  2025. }
  2026. ;
  2027. semiComma
  2028. : ';'
  2029. | ','
  2030. ;
  2031. actionlist
  2032. : action
  2033. {
  2034. parser->addListElement($1.getExpr());
  2035. $$.clear();
  2036. }
  2037. | actionlist semiComma action
  2038. {
  2039. parser->addListElement($3.getExpr());
  2040. $$.clear();
  2041. }
  2042. ;
  2043. sequentialActionlist
  2044. : sequentialAction
  2045. {
  2046. parser->addListElement($1.getExpr());
  2047. $$.clear();
  2048. }
  2049. | sequentialActionlist semiComma sequentialAction
  2050. {
  2051. parser->addListElement($3.getExpr());
  2052. $$.clear();
  2053. }
  2054. ;
  2055. sequentialAction
  2056. : action
  2057. | expression
  2058. ;
  2059. action
  2060. : actionStmt
  2061. {
  2062. $1.annotateExprWithLocation();
  2063. $$.inherit($1);
  2064. $$.setPosition($1);
  2065. }
  2066. | setMetaCommand
  2067. ;
  2068. actionStmt
  2069. : scopedActionId
  2070. | LOADXML '(' expression ')'
  2071. {
  2072. parser->processLoadXML($3, NULL);
  2073. // use an expr other than NULL to distinguish from error
  2074. $$.setExpr(createValue(no_loadxml, makeVoidType()), $1);
  2075. }
  2076. | LOADXML '(' expression ',' expression ')'
  2077. {
  2078. parser->processLoadXML($3, &$5);
  2079. // use an expr other than NULL to distinguish from error
  2080. $$.setExpr(createValue(no_loadxml, makeVoidType()), $1);
  2081. }
  2082. | UPDATE '(' startLeftSeqFilter ',' transform ')' endSelectorSequence
  2083. {
  2084. $$.setExpr(createValue(no_update, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr()), $1);
  2085. }
  2086. | BUILD '(' startTopFilter ',' ',' thorFilenameOrList optBuildFlags ')' endTopFilter
  2087. {
  2088. $$.setExpr(parser->processIndexBuild($3, NULL, NULL, $6, $7), $1);
  2089. parser->processUpdateAttr($$);
  2090. }
  2091. | BUILD '(' startTopFilter ',' recordDef ',' thorFilenameOrList optBuildFlags ')' endTopFilter
  2092. {
  2093. $$.setExpr(parser->processIndexBuild($3, &$5, NULL, $7, $8), $1);
  2094. parser->processUpdateAttr($$);
  2095. }
  2096. | BUILD '(' startTopFilter ',' recordDef ',' nullRecordDef ',' thorFilenameOrList optBuildFlags ')' endTopFilter
  2097. {
  2098. $$.setExpr(parser->processIndexBuild($3, &$5, &$7, $9, $10), $1);
  2099. parser->processUpdateAttr($$);
  2100. }
  2101. | BUILD '(' startTopFilter optBuildFlags ')' endTopFilter
  2102. {
  2103. parser->warnIfRecordPacked($3);
  2104. $$.setExpr(parser->createBuildIndexFromIndex($3, $4, NULL, $5), $1);
  2105. parser->processUpdateAttr($$);
  2106. }
  2107. | BUILD '(' startTopFilter ',' expression optBuildFlags ')' endTopFilter
  2108. {
  2109. parser->normalizeExpression($5, type_string, false);
  2110. parser->warnIfRecordPacked($3);
  2111. OwnedHqlExpr filename = $5.getExpr();
  2112. $$.setExpr(parser->createBuildIndexFromIndex($3, $6, filename, $7), $1);
  2113. parser->processUpdateAttr($$);
  2114. }
  2115. | OUTPUT '(' startTopFilter ',' optRecordDef endTopFilter optOutputFlags ')'
  2116. {
  2117. IHqlExpression *dataset = $3.getExpr();
  2118. parser->checkOutputRecord($5, true);
  2119. IHqlExpression *record = $5.getExpr();
  2120. HqlExprArray options;
  2121. $7.unwindCommaList(options);
  2122. OwnedHqlExpr select = createDatasetF(no_selectfields, dataset, record, NULL);
  2123. IHqlExpression * filename = options.ordinality() ? &options.item(0) : NULL;
  2124. if (!filename || filename->isAttribute())
  2125. {
  2126. if (queryAttribute(extendAtom, options) && !queryAttribute(namedAtom, options))
  2127. parser->reportError(ERR_EXTEND_NOT_VALID, $7, "EXTEND is only valid on NAMED outputs");
  2128. }
  2129. else
  2130. {
  2131. if (queryAttribute(extendAtom, options))
  2132. parser->reportError(ERR_NOLONGER_SUPPORTED,$7,"EXTEND is no longer supported on OUTPUT to file");
  2133. if (filename->isPure())
  2134. {
  2135. DependenciesUsed dependencies(true);
  2136. gatherDependencies(dataset, dependencies, GatherFileRead);
  2137. OwnedHqlExpr normalized = getNormalizedFilename(filename);
  2138. if (dependencies.tablesRead.find(*normalized) != NotFound)
  2139. parser->reportError(ERR_OUTPUT_TO_INPUT, $7, "Cannot OUTPUT to a file used as an input");
  2140. }
  2141. parser->warnIfRecordPacked(select, $1);
  2142. }
  2143. HqlExprArray args;
  2144. args.append(*select.getClear());
  2145. appendArray(args, options);
  2146. $$.setExpr(createValue(no_output, makeVoidType(), args), $1);
  2147. parser->processUpdateAttr($$);
  2148. }
  2149. | OUTPUT '(' startTopFilter ',' optRecordDef endTopFilter ',' pipe optCommonAttrs ')'
  2150. {
  2151. IHqlExpression *dataset = $3.getExpr();
  2152. parser->checkOutputRecord($5, true);
  2153. OwnedHqlExpr pipe = $8.getExpr();
  2154. OwnedHqlExpr record = $5.getExpr();
  2155. HqlExprArray args;
  2156. if (record->getOperator() == no_null)
  2157. args.append(*dataset);
  2158. else
  2159. {
  2160. IHqlExpression * arg = pipe;
  2161. if (arg->getOperator() == no_comma)
  2162. arg = arg->queryChild(0);
  2163. assertex(arg->getOperator() == no_pipe);
  2164. arg = arg->queryChild(0);
  2165. OwnedHqlExpr mapped = replaceSelector(arg, dataset, queryActiveTableSelector());
  2166. if (mapped != arg)
  2167. parser->reportError(ERR_ROWPIPE_AND_PROJECT, $8, "OUTPUT to PIPE with a projecting record doesn't currently work when the command is dependant on the current row");
  2168. args.append(*createDatasetF(no_selectfields, dataset, LINK(record), NULL)); //createUniqueId(), NULL));
  2169. }
  2170. pipe->unwindList(args, no_comma);
  2171. $9.unwindCommaList(args);
  2172. IHqlExpression * output = queryAttribute(outputAtom, args);
  2173. if (output)
  2174. {
  2175. unwindChildren(args, output);
  2176. args.zap(*output);
  2177. }
  2178. if (queryAttribute(csvAtom, args))
  2179. parser->checkValidCsvRecord($3, args.item(0).queryRecord());
  2180. parser->warnIfRecordPacked(&args.item(0), $1);
  2181. $$.setExpr(createValue(no_output, makeVoidType(), args), $1);
  2182. }
  2183. | OUTPUT '(' startTopFilter optOutputWuFlags ')' endTopFilter
  2184. {
  2185. IHqlExpression *dataset = $3.getExpr();
  2186. IHqlExpression *record = createValue(no_null);
  2187. OwnedHqlExpr select = createDatasetF(no_selectfields, dataset, record, NULL); //createUniqueId(), NULL);
  2188. OwnedHqlExpr flags = $4.getExpr();
  2189. if (queryAttributeInList(extendAtom, flags) && !queryAttributeInList(namedAtom, flags))
  2190. parser->reportError(ERR_EXTEND_NOT_VALID, $4, "EXTEND is only valid on NAMED outputs");
  2191. HqlExprArray args;
  2192. args.append(*select.getClear());
  2193. if (flags)
  2194. flags->unwindList(args, no_comma);
  2195. $$.setExpr(createValue(no_output, makeVoidType(), args), $1);
  2196. parser->processUpdateAttr($$);
  2197. }
  2198. | OUTPUT '(' expression optOutputWuFlags ')'
  2199. {
  2200. parser->normalizeExpression($3);
  2201. OwnedHqlExpr flags = $4.getExpr();
  2202. if (queryAttributeInList(extendAtom, flags))
  2203. parser->reportError(ERR_EXTEND_NOT_VALID, $4, "EXTEND is only valid on a dataset");
  2204. HqlExprArray args;
  2205. args.append(*$3.getExpr());
  2206. if (flags)
  2207. flags->unwindList(args, no_comma);
  2208. $$.setExpr(createValue(no_outputscalar, makeVoidType(), args), $1);
  2209. }
  2210. | OUTPUT '(' dictionary optOutputWuFlags ')'
  2211. {
  2212. parser->normalizeExpression($3);
  2213. OwnedHqlExpr flags = $4.getExpr();
  2214. if (queryAttributeInList(extendAtom, flags))
  2215. parser->reportError(ERR_EXTEND_NOT_VALID, $4, "EXTEND is only valid on a dataset");
  2216. HqlExprArray args;
  2217. args.append(*createDataset(no_datasetfromdictionary, $3.getExpr()));
  2218. if (flags)
  2219. flags->unwindList(args, no_comma);
  2220. $$.setExpr(createValue(no_output, makeVoidType(), args), $1);
  2221. parser->processUpdateAttr($$);
  2222. }
  2223. | OUTPUT '(' dataRow optOutputWuFlags ')'
  2224. {
  2225. OwnedHqlExpr flags = $4.getExpr();
  2226. if (queryAttributeInList(extendAtom, flags))
  2227. parser->reportError(ERR_EXTEND_NOT_VALID, $4, "EXTEND is only valid on a dataset");
  2228. HqlExprArray args;
  2229. args.append(*$3.getExpr());
  2230. if (flags)
  2231. flags->unwindList(args, no_comma);
  2232. $$.setExpr(createValue(no_outputscalar, makeVoidType(), args), $1);
  2233. }
  2234. | APPLY '(' startTopFilter ',' applyActions ')' endTopFilter
  2235. {
  2236. OwnedHqlExpr actions = $5.getExpr();
  2237. HqlExprArray args;
  2238. args.append(*$3.getExpr());
  2239. actions->unwindList(args, no_comma);
  2240. $$.setExpr(createValue(no_apply, makeVoidType(), args), $1);
  2241. }
  2242. | IF '(' booleanExpr ',' action ',' action ')'
  2243. {
  2244. $$.setExpr(createValue(no_if, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr()), $1);
  2245. }
  2246. | IF '(' booleanExpr ',' action ')'
  2247. {
  2248. $$.setExpr(createValue(no_if, makeVoidType(), $3.getExpr(), $5.getExpr()), $1);
  2249. }
  2250. | IFF '(' booleanExpr ',' action ',' action ')'
  2251. {
  2252. $$.setExpr(createValue(no_if, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr()), $1);
  2253. }
  2254. | IFF '(' booleanExpr ',' action ')'
  2255. {
  2256. $$.setExpr(createValue(no_if, makeVoidType(), $3.getExpr(), $5.getExpr()), $1);
  2257. }
  2258. | MAP '(' mapActionSpec ',' action ')'
  2259. {
  2260. HqlExprArray args;
  2261. $3.unwindCommaList(args);
  2262. args.append(*$5.getExpr());
  2263. $$.setExpr(createValue(no_map, makeVoidType(), args), $1);
  2264. }
  2265. | MAP '(' mapActionSpec ')'
  2266. {
  2267. HqlExprArray args;
  2268. $3.unwindCommaList(args);
  2269. args.append(*createValue(no_null, makeVoidType()));
  2270. $$.setExpr(createValue(no_map, makeVoidType(), args), $1);
  2271. }
  2272. | CASE '(' expression ',' beginList caseActionSpec ',' action ')'
  2273. {
  2274. parser->normalizeExpression($3);
  2275. HqlExprArray args;
  2276. parser->endList(args);
  2277. parser->checkCaseForDuplicates(args, $6);
  2278. args.add(*$3.getExpr(),0);
  2279. args.append(*$8.getExpr());
  2280. $$.setExpr(createValue(no_case, makeVoidType(), args), $1);
  2281. }
  2282. | CASE '(' expression ',' beginList caseActionSpec ')'
  2283. {
  2284. parser->normalizeExpression($3);
  2285. HqlExprArray args;
  2286. parser->endList(args);
  2287. parser->checkCaseForDuplicates(args, $6);
  2288. args.add(*$3.getExpr(),0);
  2289. args.append(*createValue(no_null, makeVoidType()));
  2290. $$.setExpr(createValue(no_case, makeVoidType(), args), $1);
  2291. }
  2292. | CASE '(' expression ',' beginList action ')'
  2293. {
  2294. parser->normalizeExpression($3);
  2295. // change error to warning.
  2296. parser->reportWarning(WRN_CASENOCONDITION, $1.pos, "CASE does not have any conditions");
  2297. HqlExprArray list;
  2298. parser->endList(list);
  2299. ::Release($3.getExpr());
  2300. $$.setExpr($6.getExpr(), $1);
  2301. }
  2302. | WAIT '(' event ')'
  2303. {
  2304. $$.setExpr(createValue(no_wait, makeVoidType(), $3.getExpr()), $1);
  2305. }
  2306. | WAIT '(' event ',' IF '(' booleanExpr ')' ')'
  2307. {
  2308. $$.setExpr(createValue(no_wait, makeVoidType(), $3.getExpr(), $7.getExpr()), $1);
  2309. }
  2310. | NOTIFY '(' expression ',' expression ')'
  2311. {
  2312. parser->normalizeExpression($3, type_string, false);
  2313. parser->normalizeExpression($5, type_string, false);
  2314. OwnedHqlExpr event = createValue(no_event, makeEventType(), $3.getExpr(), $5.getExpr());
  2315. $$.setExpr(createValue(no_notify, makeVoidType(), event.getClear()), $1);
  2316. }
  2317. | NOTIFY '(' expression ',' expression ',' expression ')'
  2318. {
  2319. parser->normalizeExpression($3, type_string, false);
  2320. parser->normalizeExpression($5, type_string, false);
  2321. parser->normalizeExpression($7, type_string, false);
  2322. OwnedHqlExpr event = createValue(no_event, makeEventType(), $3.getExpr(), $5.getExpr());
  2323. $$.setExpr(createValue(no_notify, makeVoidType(), event.getClear(), $7.getExpr()), $1);
  2324. }
  2325. | NOTIFY '(' eventObject ')'
  2326. {
  2327. $$.setExpr(createValue(no_notify, makeVoidType(), $3.getExpr()), $1);
  2328. }
  2329. | NOTIFY '(' eventObject ',' expression ')'
  2330. {
  2331. parser->normalizeExpression($5, type_string, false);
  2332. $$.setExpr(createValue(no_notify, makeVoidType(), $3.getExpr(), $5.getExpr()), $1);
  2333. }
  2334. | NOFOLD '(' action ')'
  2335. {
  2336. $$.setExpr(createValue(no_nofold, makeVoidType(), $3.getExpr()), $1);
  2337. }
  2338. | NOTHOR '(' action ')'
  2339. {
  2340. $$.setExpr(createValue(no_nothor, makeVoidType(), $3.getExpr()), $1);
  2341. }
  2342. | failAction
  2343. | SEQUENTIAL '(' beginList sequentialActionlist optSemiComma ')'
  2344. {
  2345. HqlExprArray actions;
  2346. parser->endList(actions);
  2347. $$.setExpr(createValue(no_sequential, makeVoidType(), actions), $1);
  2348. }
  2349. | PARALLEL '(' beginList sequentialActionlist optSemiComma ')'
  2350. {
  2351. HqlExprArray actions;
  2352. parser->endList(actions);
  2353. $$.setExpr(createValue(no_parallel, makeVoidType(), actions), $1);
  2354. }
  2355. | ORDERED '(' beginList sequentialActionlist optSemiComma ')'
  2356. {
  2357. HqlExprArray actions;
  2358. parser->endList(actions);
  2359. $$.setExpr(createValue(no_orderedactionlist, makeVoidType(), actions), $1);
  2360. }
  2361. | SOAPCALL '(' expression ',' expression ',' recordDef ')'
  2362. {
  2363. parser->normalizeExpression($3, type_stringorunicode, false);
  2364. parser->normalizeExpression($5, type_stringorunicode, false);
  2365. parser->checkSoapRecord($7);
  2366. $$.setExpr(createValue(no_soapcall, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr()), $1);
  2367. }
  2368. | SOAPCALL '(' expression ',' expression ',' recordDef ',' soapFlags ')'
  2369. {
  2370. parser->normalizeExpression($3, type_stringorunicode, false);
  2371. parser->normalizeExpression($5, type_stringorunicode, false);
  2372. parser->checkSoapRecord($7);
  2373. $$.setExpr(createValueF(no_soapcall, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $9.getExpr(), NULL), $1);
  2374. }
  2375. | SOAPCALL '(' expression ',' expression ',' recordDef ',' transform ')'
  2376. {
  2377. parser->normalizeExpression($3, type_stringorunicode, false);
  2378. parser->normalizeExpression($5, type_stringorunicode, false);
  2379. $$.setExpr(createValue(no_newsoapcall, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $9.getExpr()), $1);
  2380. }
  2381. | SOAPCALL '(' expression ',' expression ',' recordDef ',' transform ',' soapFlags ')'
  2382. {
  2383. parser->normalizeExpression($3, type_stringorunicode, false);
  2384. parser->normalizeExpression($5, type_stringorunicode, false);
  2385. $$.setExpr(createValueF(no_newsoapcall, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr(), NULL), $1);
  2386. }
  2387. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ')' endTopLeftFilter endSelectorSequence
  2388. {
  2389. parser->normalizeExpression($5, type_stringorunicode, false);
  2390. parser->normalizeExpression($7, type_stringorunicode, false);
  2391. parser->checkSoapRecord($9);
  2392. $$.setExpr(createValueF(no_soapaction_ds, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $9.getExpr(), $12.getExpr(), NULL), $1);
  2393. }
  2394. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ',' soapFlags ')' endTopLeftFilter endSelectorSequence
  2395. {
  2396. parser->normalizeExpression($5, type_stringorunicode, false);
  2397. parser->normalizeExpression($7, type_stringorunicode, false);
  2398. parser->checkSoapRecord($9);
  2399. $$.setExpr(createValueF(no_soapaction_ds, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr(), $14.getExpr(), NULL), $1);
  2400. }
  2401. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ',' transform ')' endTopLeftFilter endSelectorSequence
  2402. {
  2403. parser->normalizeExpression($5, type_stringorunicode, false);
  2404. parser->normalizeExpression($7, type_stringorunicode, false);
  2405. $$.setExpr(createValueF(no_newsoapaction_ds, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr(), $14.getExpr(), NULL));
  2406. $$.setPosition($1);
  2407. }
  2408. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ',' transform ',' soapFlags ')' endTopLeftFilter endSelectorSequence
  2409. {
  2410. parser->normalizeExpression($5, type_stringorunicode, false);
  2411. parser->normalizeExpression($7, type_stringorunicode, false);
  2412. $$.setExpr(createValueF(no_newsoapaction_ds, makeVoidType(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr(), $13.getExpr(), $16.getExpr(), NULL));
  2413. $$.setPosition($1);
  2414. }
  2415. | KEYDIFF '(' dataSet ',' dataSet ',' expression keyDiffFlags ')'
  2416. {
  2417. if (!isKey($3.queryExpr()))
  2418. parser->reportError(ERR_EXPECTED_INDEX,$3,"Expected an index");
  2419. if (!isKey($5.queryExpr()))
  2420. parser->reportError(ERR_EXPECTED_INDEX,$5,"Expected an index");
  2421. if (!recordTypesMatch($3.queryExpr(), $5.queryExpr()))
  2422. parser->reportError(ERR_TYPEMISMATCH_RECORD, $4, "Indexes must have the same structure");
  2423. parser->normalizeExpression($7, type_string, false);
  2424. $$.setExpr(createValueFromCommaList(no_keydiff, makeVoidType(), createComma($3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr())));
  2425. $$.setPosition($1);
  2426. }
  2427. | KEYPATCH '(' dataSet ',' expression ',' expression keyDiffFlags ')'
  2428. {
  2429. if (!isKey($3.queryExpr()))
  2430. parser->reportError(ERR_EXPECTED_INDEX,$3,"Expected an index");
  2431. parser->normalizeExpression($5, type_string, false);
  2432. parser->normalizeExpression($7, type_string, false);
  2433. $$.setExpr(createValueFromCommaList(no_keypatch, makeVoidType(), createComma($3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr())));
  2434. $$.setPosition($1);
  2435. }
  2436. | EVALUATE '(' expression ')'
  2437. {
  2438. parser->normalizeExpression($3);
  2439. $$.setExpr(createValue(no_evaluate_stmt, makeVoidType(), $3.getExpr()));
  2440. $$.setPosition($1);
  2441. }
  2442. | EVALUATE '(' action ')'
  2443. {
  2444. $$.inherit($3);
  2445. }
  2446. | EVALUATE '(' abstractModule ')'
  2447. {
  2448. OwnedHqlExpr abstract = $3.getExpr();
  2449. OwnedHqlExpr concrete = parser->checkConcreteModule($3, abstract);
  2450. $$.setExpr(parser->createEvaluateOutputModule($3, concrete, concrete, no_evaluate_stmt, NULL), $1);
  2451. }
  2452. | EVALUATE '(' abstractModule ',' knownOrUnknownId ')'
  2453. {
  2454. OwnedHqlExpr abstract = $3.getExpr();
  2455. OwnedHqlExpr concrete = parser->checkConcreteModule($3, abstract);
  2456. $$.setExpr(parser->createEvaluateOutputModule($3, concrete, concrete, no_evaluate_stmt, $5.getId()), $1);
  2457. }
  2458. | DISTRIBUTION '(' startTopFilter beginList optDistributionFlags ignoreDummyList ')' endTopFilter
  2459. {
  2460. $$.setExpr(createValue(no_distribution, makeVoidType(), $3.getExpr(), $5.getExpr()), $1);
  2461. }
  2462. | DISTRIBUTION '(' startTopFilter beginList ',' sortList optDistributionFlags ')' endTopFilter
  2463. {
  2464. HqlExprArray sortItems;
  2465. parser->endList(sortItems);
  2466. IHqlExpression * dataset = $3.getExpr();
  2467. IHqlExpression * fields = parser->processSortList($6, no_sortlist, dataset, sortItems, NULL, NULL);
  2468. $$.setExpr(createValue(no_distribution, makeVoidType(), dataset, fields, $7.getExpr()));
  2469. }
  2470. | assertAction
  2471. | GLOBAL '(' action ')'
  2472. {
  2473. $$.setExpr($3.getExpr());
  2474. $$.setPosition($1);
  2475. }
  2476. | GLOBAL '(' action ',' expression ')'
  2477. {
  2478. parser->normalizeExpression($5, type_string, true);
  2479. if (isBlankString($5.queryExpr()))
  2480. {
  2481. $5.release();
  2482. $$.setExpr($3.getExpr());
  2483. }
  2484. else
  2485. $$.setExpr(createValueF(no_cluster, makeVoidType(), $3.getExpr(), $5.getExpr(), NULL));
  2486. $$.setPosition($1);
  2487. }
  2488. | OUTPUT '(' abstractModule ')'
  2489. {
  2490. OwnedHqlExpr abstract = $3.getExpr();
  2491. OwnedHqlExpr concrete = parser->checkConcreteModule($3, abstract);
  2492. $$.setExpr(parser->createEvaluateOutputModule($3, concrete, concrete, no_output, NULL));
  2493. $$.setPosition($1);
  2494. }
  2495. | OUTPUT '(' abstractModule ',' abstractModule ')'
  2496. {
  2497. OwnedHqlExpr abstract = $3.getExpr();
  2498. OwnedHqlExpr concrete = parser->checkConcreteModule($3, abstract);
  2499. OwnedHqlExpr iface = $5.getExpr();
  2500. $$.setExpr(parser->createEvaluateOutputModule($3, concrete, iface, no_output, NULL));
  2501. $$.setPosition($1);
  2502. }
  2503. | ALLNODES '(' beginList actionlist ')'
  2504. {
  2505. HqlExprArray actions;
  2506. parser->endList(actions);
  2507. $$.setExpr(createValue(no_allnodes, makeVoidType(), createCompound(actions)));
  2508. $$.setPosition($1);
  2509. }
  2510. | '[' beginList actionlist ']'
  2511. {
  2512. HqlExprArray actions;
  2513. parser->endList(actions);
  2514. $$.setExpr(createActionList(no_orderedactionlist, actions), $1);
  2515. }
  2516. | OUTPUT '(' action ')'
  2517. {
  2518. parser->reportError(ERR_EXPECTED, $3, "OUTPUT cannot be applied to an action");
  2519. $$.inherit($3);
  2520. }
  2521. ;
  2522. failAction
  2523. : FAIL '(' expression ',' expression ')'
  2524. {
  2525. parser->normalizeExpression($3, type_int, false);
  2526. parser->normalizeExpression($5, type_string, false);
  2527. $$.setExpr(createValue(no_fail, makeVoidType(), $3.getExpr(), $5.getExpr()));
  2528. $$.setPosition($1);
  2529. }
  2530. | FAIL '(' expression ')'
  2531. {
  2532. parser->normalizeExpression($3);
  2533. parser->checkIntegerOrString($3);
  2534. $$.setExpr(createValue(no_fail, makeVoidType(), $3.getExpr()));
  2535. $$.setPosition($1);
  2536. }
  2537. | FAIL '(' ')'
  2538. {
  2539. $$.setExpr(createValue(no_fail, makeVoidType()));
  2540. $$.setPosition($1);
  2541. }
  2542. | FAIL {
  2543. $$.setExpr(createValue(no_fail, makeVoidType()));
  2544. $$.setPosition($1);
  2545. }
  2546. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN action ';' endInlineFunctionToken
  2547. {
  2548. Owned<ITypeInfo> retType = $1.getType();
  2549. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  2550. }
  2551. | WHEN '(' action ',' action sideEffectOptions ')'
  2552. {
  2553. OwnedHqlExpr options = $6.getExpr();
  2554. if (options)
  2555. $$.setExpr(createValueF(no_executewhen, makeVoidType(), $3.getExpr(), $5.getExpr(), options.getClear(), NULL), $1);
  2556. else
  2557. $$.setExpr(createCompound($5.getExpr(), $3.getExpr()), $1);
  2558. }
  2559. ;
  2560. assertActions
  2561. : assertAction
  2562. | assertActions ',' assertAction
  2563. {
  2564. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  2565. $$.setPosition($1);
  2566. }
  2567. ;
  2568. assertAction
  2569. : TOK_ASSERT '(' expression assertFlags ')'
  2570. {
  2571. parser->normalizeExpression($3, type_boolean, false);
  2572. $$.setExpr(parser->createAssert($3, NULL, $4));
  2573. $$.setPosition($1);
  2574. }
  2575. | TOK_ASSERT '(' expression ',' expression assertFlags ')'
  2576. {
  2577. parser->normalizeExpression($3, type_boolean, false);
  2578. parser->normalizeExpression($5);
  2579. $$.setExpr(parser->createAssert($3, &$5, $6));
  2580. $$.setPosition($1);
  2581. }
  2582. ;
  2583. assertFlags
  2584. : { $$.setNullExpr(); }
  2585. | ',' FAIL
  2586. {
  2587. $$.setExpr(createAttribute(failAtom));
  2588. $$.setPosition($2);
  2589. }
  2590. | ',' TOK_CONST
  2591. {
  2592. $$.setExpr(createAttribute(constAtom));
  2593. $$.setPosition($2);
  2594. }
  2595. ;
  2596. optBuildFlags
  2597. : { $$.setNullExpr(); $$.clearPosition(); }
  2598. | ',' buildFlags { $$.setExpr($2.getExpr(), $1); }
  2599. ;
  2600. buildFlags
  2601. : buildFlag
  2602. | buildFlag ',' buildFlags
  2603. {
  2604. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  2605. $$.setPosition($1);
  2606. }
  2607. ;
  2608. buildFlag
  2609. : PARALLEL { $$.setExpr(createAttribute(parallelAtom)); $$.setPosition($1); }
  2610. | OVERWRITE { $$.setExpr(createAttribute(overwriteAtom)); $$.setPosition($1); }
  2611. | NOOVERWRITE { $$.setExpr(createAttribute(noOverwriteAtom)); $$.setPosition($1); }
  2612. | BACKUP { $$.setExpr(createAttribute(backupAtom)); $$.setPosition($1); }
  2613. | NAMED '(' constExpression ')'
  2614. {
  2615. parser->normalizeStoredNameExpression($3);
  2616. $$.setExpr(createAttribute(namedAtom, $3.getExpr()));
  2617. $$.setPosition($1);
  2618. }
  2619. | DATASET '(' dataSet ')'
  2620. {
  2621. OwnedHqlExpr ds = $3.getExpr();
  2622. if (ds->getOperator() != no_table)
  2623. parser->reportError(ERR_EXPECTED_DATASET, $3, "Expected parameter to be a DATASET definition");
  2624. IHqlExpression * record = createAttribute(recordAtom, LINK(ds->queryRecord()));
  2625. IHqlExpression * name = createAttribute(nameAtom, LINK(ds->queryChild(0)));
  2626. $$.setExpr(createComma(record, name));
  2627. $$.setPosition($1);
  2628. }
  2629. | commonAttribute
  2630. | SORTED { $$.setExpr(createAttribute(sortedAtom)); $$.setPosition($1); }
  2631. | DISTRIBUTE '(' startTopFilter startDistributeAttrs optDistributeAttrs ')' endTopFilter
  2632. {
  2633. IHqlExpression * arg = $3.getExpr();
  2634. $5.release(); // They are only there to prevent s/r error with the dataset form.
  2635. if (!isKey(arg))
  2636. parser->reportError(ERR_EXPECTED_INDEX,$3,"Expected an index");
  2637. $$.setExpr(createValue(no_distributer, makeNullType(), arg));
  2638. $$.setPosition($1);
  2639. }
  2640. | MERGE {
  2641. $$.setExpr(createAttribute(mergeAtom));
  2642. $$.setPosition($1);
  2643. }
  2644. | skewAttribute
  2645. | THRESHOLD '(' expression ')'
  2646. {
  2647. parser->normalizeExpression($3, type_numeric, true);
  2648. $$.setExpr(createAttribute(thresholdAtom, $3.getExpr()));
  2649. }
  2650. | FEW {
  2651. $$.setExpr(createAttribute(fewAtom));
  2652. $$.setPosition($1);
  2653. }
  2654. | PERSIST {
  2655. $$.setExpr(createAttribute(persistAtom));
  2656. $$.setPosition($1);
  2657. }
  2658. | UPDATE {
  2659. $$.setExpr(createComma(createAttribute(updateAtom), createAttribute(overwriteAtom)));
  2660. $$.setPosition($1);
  2661. }
  2662. | expireAttr
  2663. | NOROOT {
  2664. $$.setExpr(createComma(createAttribute(noRootAtom), createLocalAttribute()));
  2665. $$.setPosition($1);
  2666. }
  2667. | SORT KEYED {
  2668. $$.setExpr(createAttribute(sort_KeyedAtom));
  2669. $$.setPosition($1);
  2670. }
  2671. | SORT ALL {
  2672. $$.setExpr(createAttribute(sort_AllAtom));
  2673. $$.setPosition($1);
  2674. }
  2675. | clusterAttr
  2676. | WIDTH '(' expression ')'
  2677. {
  2678. parser->normalizeExpression($3, type_numeric, false);
  2679. $$.setExpr(createExprAttribute(widthAtom, $3.getExpr()), $1);
  2680. }
  2681. | SET '(' expression ',' expression ')'
  2682. {
  2683. parser->normalizeExpression($3, type_stringorunicode, false);
  2684. parser->normalizeExpression($5);
  2685. $$.setExpr(createExprAttribute(setAtom, $3.getExpr(), $5.getExpr()));
  2686. $$.setPosition($1);
  2687. }
  2688. | DISTRIBUTED {
  2689. $$.setExpr(createComma(createAttribute(noRootAtom), createLocalAttribute()));
  2690. $$.setPosition($1);
  2691. }
  2692. | DISTRIBUTED '(' expression ')'
  2693. {
  2694. parser->normalizeExpression($3, type_int, false);
  2695. $$.setExpr(createComma(createAttribute(noRootAtom), createExprAttribute(distributedAtom, $3.getExpr()), createLocalAttribute()));
  2696. $$.setPosition($1);
  2697. }
  2698. | COMPRESSED '(' compressMode ')'
  2699. {
  2700. $$.setExpr(createExprAttribute(compressedAtom, $3.getExpr()));
  2701. $$.setPosition($1);
  2702. }
  2703. | DEDUP
  2704. {
  2705. $$.setExpr(createAttribute(dedupAtom), $1);
  2706. }
  2707. | FILEPOSITION optConstBoolArg
  2708. {
  2709. $$.setExpr(createExprAttribute(filepositionAtom, $2.getExpr()), $1);
  2710. }
  2711. ;
  2712. localAttribute
  2713. : LOCAL {
  2714. $$.setExpr(createLocalAttribute());
  2715. $$.setPosition($1);
  2716. }
  2717. | NOLOCAL {
  2718. $$.setExpr(createAttribute(noLocalAtom));
  2719. $$.setPosition($1);
  2720. }
  2721. ;
  2722. optCommonAttrs
  2723. : { $$.setNullExpr(); }
  2724. | ',' commonAttribute optCommonAttrs
  2725. {
  2726. $$.setExpr(createComma($2.getExpr(), $3.getExpr()));
  2727. $$.setPosition($3);
  2728. }
  2729. ;
  2730. commonAttribute
  2731. : localAttribute
  2732. | hintAttribute
  2733. ;
  2734. hintAttribute
  2735. : HINT '(' hintList ')'
  2736. {
  2737. HqlExprArray args;
  2738. $3.unwindCommaList(args);
  2739. $$.setExpr(createExprAttribute(hintAtom, args));
  2740. $$.setPosition($1);
  2741. }
  2742. ;
  2743. hintList
  2744. : hintItem
  2745. | hintList ',' hintItem
  2746. {
  2747. $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1);
  2748. }
  2749. ;
  2750. hintItem
  2751. : hintName
  2752. {
  2753. $$.setExpr(createExprAttribute($1.getId()->lower()));
  2754. $$.setPosition($1);
  2755. }
  2756. | hintName '(' beginList hintExprList ')'
  2757. {
  2758. HqlExprArray args;
  2759. parser->endList(args);
  2760. $$.setExpr(createExprAttribute($1.getId()->lower(), args));
  2761. $$.setPosition($1);
  2762. }
  2763. ;
  2764. hintName
  2765. : UNKNOWN_ID
  2766. | OUTPUT { $$.setId(outputId); }
  2767. ;
  2768. hintExprList
  2769. : hintExpr
  2770. {
  2771. parser->addListElement($1.getExpr());
  2772. $$.clear();
  2773. }
  2774. | hintExprList ',' hintExpr
  2775. {
  2776. parser->addListElement($3.getExpr());
  2777. $$.clear();
  2778. }
  2779. ;
  2780. hintExpr
  2781. : expression
  2782. {
  2783. parser->normalizeExpression($1);
  2784. $$.inherit($1);
  2785. }
  2786. | expression DOTDOT expression
  2787. {
  2788. parser->normalizeExpression($1);
  2789. parser->normalizeExpression($3);
  2790. $$.setExpr(createValue(no_range, makeNullType(), $1.getExpr(), $3.getExpr()));
  2791. }
  2792. | DOTDOT expression
  2793. {
  2794. parser->normalizeExpression($2);
  2795. $$.setExpr(createValue(no_rangeto, makeNullType(), $2.getExpr()));
  2796. }
  2797. | expression DOTDOT {
  2798. parser->normalizeExpression($1);
  2799. $$.setExpr(createValue(no_rangefrom, makeNullType(), $1.getExpr()));
  2800. }
  2801. | UNKNOWN_ID
  2802. {
  2803. $$.setExpr(createAttribute($1.getId()->lower()), $1);
  2804. }
  2805. ;
  2806. expireAttr
  2807. : EXPIRE {
  2808. $$.setExpr(createAttribute(expireAtom));
  2809. $$.setPosition($1);
  2810. }
  2811. | EXPIRE '(' expression ')'
  2812. {
  2813. parser->normalizeExpression($3, type_int, true);
  2814. $$.setExpr(createAttribute(expireAtom, $3.getExpr()));
  2815. $$.setPosition($1);
  2816. }
  2817. ;
  2818. optDatasetFlags
  2819. : { $$.setNullExpr(); }
  2820. | ',' datasetFlags { $$.inherit($2); }
  2821. ;
  2822. datasetFlags
  2823. : datasetFlag
  2824. | datasetFlag ',' datasetFlags
  2825. { $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1); }
  2826. ;
  2827. datasetFlag
  2828. : DISTRIBUTED {
  2829. $$.setExpr(createExprAttribute(distributedAtom));
  2830. $$.setPosition($1);
  2831. }
  2832. | localAttribute
  2833. ;
  2834. optIndexFlags
  2835. : { $$.setNullExpr(); $$.clearPosition(); }
  2836. | ',' indexFlags { $$.setExpr($2.getExpr()); $$.setPosition($1); }
  2837. ;
  2838. indexFlags
  2839. : indexFlag
  2840. | indexFlag ',' indexFlags
  2841. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); $$.setPosition($1); }
  2842. ;
  2843. indexFlag
  2844. : SORTED { $$.setExpr(createAttribute(sortedAtom)); $$.setPosition($1); }
  2845. | STEPPED { $$.setExpr(createExprAttribute(steppedAtom)); $$.setPosition($1); }
  2846. | STEPPED '(' expressionList ')'
  2847. {
  2848. HqlExprArray args;
  2849. $3.unwindCommaList(args);
  2850. $$.setExpr(createExprAttribute(steppedAtom, args));
  2851. $$.setPosition($1);
  2852. }
  2853. | PRELOAD { $$.setExpr(createAttribute(preloadAtom)); $$.setPosition($1); }
  2854. | OPT { $$.setExpr(createAttribute(optAtom)); $$.setPosition($1); }
  2855. | SORT KEYED {
  2856. $$.setExpr(createAttribute(sort_KeyedAtom));
  2857. $$.setPosition($1);
  2858. }
  2859. | SORT ALL {
  2860. $$.setExpr(createAttribute(sort_AllAtom));
  2861. $$.setPosition($1);
  2862. }
  2863. | REMOTE {
  2864. $$.setExpr(createExprAttribute(distributedAtom));
  2865. $$.setPosition($1);
  2866. }
  2867. | DISTRIBUTED {
  2868. $$.setExpr(createExprAttribute(distributedAtom));
  2869. $$.setPosition($1);
  2870. }
  2871. | DISTRIBUTED '(' expression ')'
  2872. {
  2873. parser->normalizeExpression($3, type_numeric, false);
  2874. $$.setExpr(createExprAttribute(distributedAtom, $3.getExpr()));
  2875. $$.setPosition($1);
  2876. }
  2877. | TOK_FIXED
  2878. {
  2879. $$.setExpr(createAttribute(fixedAtom));
  2880. $$.setPosition($1);
  2881. }
  2882. | COMPRESSED '(' compressMode ')'
  2883. {
  2884. $$.setExpr(createExprAttribute(compressedAtom, $3.getExpr()));
  2885. $$.setPosition($1);
  2886. }
  2887. | DYNAMIC
  2888. {
  2889. $$.setExpr(createAttribute(dynamicAtom));
  2890. $$.setPosition($1);
  2891. }
  2892. | UNORDERED { $$.setExpr(createAttribute(unorderedAtom)); $$.setPosition($1); }
  2893. | FILEPOSITION optConstBoolArg
  2894. {
  2895. $$.setExpr(createExprAttribute(filepositionAtom, $2.getExpr()), $1);
  2896. }
  2897. | commonAttribute
  2898. ;
  2899. compressMode
  2900. : FIRST {
  2901. $$.setExpr(createAttribute(firstAtom));
  2902. $$.setPosition($1);
  2903. }
  2904. | LZW
  2905. {
  2906. $$.setExpr(createAttribute(lzwAtom));
  2907. $$.setPosition($1);
  2908. }
  2909. | ROW
  2910. {
  2911. $$.setExpr(createAttribute(rowAtom));
  2912. $$.setPosition($1);
  2913. }
  2914. ;
  2915. optOutputFlags
  2916. : { $$.setNullExpr(); $$.clearPosition(); }
  2917. | ',' outputFlags { $$.setExpr($2.getExpr()); $$.setPosition($1); }
  2918. ;
  2919. outputFlags
  2920. : outputFlag
  2921. | outputFlags ',' outputFlag
  2922. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); $$.setPosition($1); }
  2923. ;
  2924. outputFlag
  2925. : EXTEND {
  2926. $$.setExpr(createAttribute(extendAtom));
  2927. }
  2928. | CSV {
  2929. $$.setExpr(createAttribute(csvAtom));
  2930. $$.setPosition($1);
  2931. }
  2932. | CSV '(' csvOptions ')'
  2933. {
  2934. HqlExprArray args;
  2935. $3.unwindCommaList(args);
  2936. $$.setExpr(createExprAttribute(csvAtom, args));
  2937. $$.setPosition($1);
  2938. }
  2939. | COMPRESSED {
  2940. $$.setExpr(createAttribute(compressedAtom));
  2941. $$.setPosition($1);
  2942. }
  2943. | __COMPRESSED__ {
  2944. $$.setExpr(createAttribute(__compressed__Atom));
  2945. $$.setPosition($1);
  2946. }
  2947. | __GROUPED__ {
  2948. $$.setExpr(createAttribute(groupedAtom));
  2949. $$.setPosition($1);
  2950. }
  2951. | OVERWRITE {
  2952. $$.setExpr(createAttribute(overwriteAtom));
  2953. $$.setPosition($1);
  2954. }
  2955. | NOOVERWRITE {
  2956. $$.setExpr(createAttribute(noOverwriteAtom));
  2957. $$.setPosition($1);
  2958. }
  2959. | BACKUP {
  2960. $$.setExpr(createAttribute(backupAtom));
  2961. $$.setPosition($1);
  2962. }
  2963. | PERSIST {
  2964. $$.setExpr(createAttribute(persistAtom));
  2965. $$.setPosition($1);
  2966. }
  2967. | XML_TOKEN {
  2968. $$.setExpr(createAttribute(xmlAtom));
  2969. $$.setPosition($1);
  2970. }
  2971. | XML_TOKEN '(' xmlOptions ')'
  2972. {
  2973. HqlExprArray args;
  2974. $3.unwindCommaList(args);
  2975. $$.setExpr(createExprAttribute(xmlAtom, args), $1);
  2976. }
  2977. | UPDATE {
  2978. $$.setExpr(createComma(createAttribute(updateAtom), createAttribute(overwriteAtom)), $1);
  2979. }
  2980. | expireAttr
  2981. | ENCRYPT '(' expression ')'
  2982. {
  2983. parser->normalizeExpression($3, type_data, false);
  2984. $$.setExpr(createExprAttribute(encryptAtom, $3.getExpr()));
  2985. $$.setPosition($1);
  2986. }
  2987. | clusterAttr
  2988. | WIDTH '(' expression ')'
  2989. {
  2990. parser->normalizeExpression($3, type_numeric, false);
  2991. $$.setExpr(createExprAttribute(widthAtom, $3.getExpr()), $1);
  2992. }
  2993. | commonAttribute
  2994. | __OWNED__
  2995. {
  2996. //$$.setExpr(createAttribute(jobOwnedAtom), $1);
  2997. $$.setExpr(createAttribute(ownedAtom), $1);
  2998. }
  2999. | thorFilenameOrList
  3000. {
  3001. //Careful with dynamic...
  3002. if (($1.getOperator() != no_comma) && !$1.queryExpr()->isAttribute())
  3003. parser->normalizeExpression($1, type_string, false);
  3004. $$.inherit($1);
  3005. }
  3006. | FIRST '(' constExpression ')'
  3007. {
  3008. parser->normalizeExpression($3, type_int, false);
  3009. $$.setExpr(createAttribute(firstAtom, $3.getExpr()));
  3010. $$.setPosition($1);
  3011. }
  3012. | THOR {
  3013. $$.setExpr(createAttribute(diskAtom));
  3014. $$.setPosition($1);
  3015. }
  3016. | NAMED '(' constExpression ')'
  3017. {
  3018. parser->normalizeStoredNameExpression($3);
  3019. $$.setExpr(createAttribute(namedAtom, $3.getExpr()));
  3020. $$.setPosition($1);
  3021. }
  3022. | STORED {
  3023. $$.setExpr(createAttribute(workunitAtom)); // need a better keyword, but WORKUNIT is no good
  3024. $$.setPosition($1);
  3025. }
  3026. | NOXPATH {
  3027. $$.setExpr(createAttribute(noXpathAtom));
  3028. $$.setPosition($1);
  3029. }
  3030. ;
  3031. soapFlags
  3032. : soapFlag
  3033. | soapFlags ',' soapFlag
  3034. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); $$.setPosition($1); }
  3035. ;
  3036. soapFlag
  3037. : HEADING '(' expression optCommaExpression ')'
  3038. {
  3039. parser->normalizeExpression($3, type_string, false);
  3040. if ($4.queryExpr())
  3041. parser->normalizeExpression($4, type_string, false);
  3042. $$.setExpr(createExprAttribute(headingAtom, $3.getExpr(), $4.getExpr()));
  3043. $$.setPosition($1);
  3044. }
  3045. | SEPARATOR '(' expression ')'
  3046. {
  3047. parser->normalizeExpression($3, type_string, true);
  3048. $$.setExpr(createAttribute(separatorAtom, $3.getExpr()));
  3049. $$.setPosition($1);
  3050. }
  3051. | XPATH '(' expression ')'
  3052. {
  3053. //MORE: Really type_utf8 - and in lots of other places!
  3054. parser->normalizeExpression($3, type_string, false);
  3055. parser->validateXPath($3);
  3056. $$.setExpr(createExprAttribute(xpathAtom, $3.getExpr()));
  3057. $$.setPosition($1);
  3058. }
  3059. | GROUP {
  3060. $$.setExpr(createAttribute(groupAtom));
  3061. $$.setPosition($1);
  3062. }
  3063. | MERGE '(' expression ')'
  3064. {
  3065. parser->normalizeExpression($3, type_int, false);
  3066. $$.setExpr(createExprAttribute(mergeAtom, $3.getExpr()));
  3067. $$.setPosition($1);
  3068. }
  3069. | PARALLEL '(' expression ')'
  3070. {
  3071. parser->normalizeExpression($3, type_int, false);
  3072. $$.setExpr(createExprAttribute(parallelAtom, $3.getExpr()));
  3073. $$.setPosition($1);
  3074. }
  3075. | RETRY '(' expression ')'
  3076. {
  3077. parser->normalizeExpression($3, type_int, false);
  3078. $$.setExpr(createExprAttribute(retryAtom, $3.getExpr()));
  3079. $$.setPosition($1);
  3080. }
  3081. | TIMEOUT '(' expression ')'
  3082. {
  3083. parser->normalizeExpression($3, type_real, false);
  3084. $$.setExpr(createExprAttribute(timeoutAtom, $3.getExpr()));
  3085. $$.setPosition($1);
  3086. }
  3087. | TIMELIMIT '(' expression ')'
  3088. {
  3089. parser->normalizeExpression($3, type_real, false);
  3090. $$.setExpr(createExprAttribute(timeLimitAtom, $3.getExpr()));
  3091. $$.setPosition($1);
  3092. }
  3093. | onFailAction
  3094. | TOK_LOG
  3095. {
  3096. $$.setExpr(createAttribute(logAtom));
  3097. $$.setPosition($1);
  3098. }
  3099. | TRIM {
  3100. $$.setExpr(createAttribute(trimAtom));
  3101. $$.setPosition($1);
  3102. }
  3103. | SOAPACTION '(' expression ')'
  3104. {
  3105. parser->normalizeExpression($3, type_string, false);
  3106. $$.setExpr(createExprAttribute(soapActionAtom, $3.getExpr()));
  3107. $$.setPosition($1);
  3108. }
  3109. | HTTPHEADER '(' expression optCommaExpression ')'
  3110. {
  3111. parser->normalizeExpression($3, type_string, false);
  3112. if ($4.queryExpr())
  3113. parser->normalizeExpression($4, type_string, false);
  3114. $$.setExpr(createExprAttribute(httpHeaderAtom, $3.getExpr(), $4.getExpr()));
  3115. $$.setPosition($1);
  3116. }
  3117. | PROXYADDRESS '(' expression optCommaExpression ')'
  3118. {
  3119. parser->normalizeExpression($3, type_string, false);
  3120. if ($4.queryExpr())
  3121. parser->normalizeExpression($4, type_string, false);
  3122. $$.setExpr(createExprAttribute(proxyAddressAtom, $3.getExpr(), $4.getExpr()));
  3123. $$.setPosition($1);
  3124. }
  3125. | LITERAL
  3126. {
  3127. $$.setExpr(createAttribute(literalAtom));
  3128. $$.setPosition($1);
  3129. }
  3130. | ENCODING
  3131. {
  3132. $$.setExpr(createAttribute(encodingAtom));
  3133. $$.setPosition($1);
  3134. }
  3135. | NAMESPACE '(' expression ')'
  3136. {
  3137. parser->normalizeExpression($3, type_string, false);
  3138. $$.setExpr(createExprAttribute(namespaceAtom, $3.getExpr()));
  3139. $$.setPosition($1);
  3140. }
  3141. | NAMESPACE '(' expression ',' expression ')'
  3142. {
  3143. parser->normalizeExpression($3, type_string, false);
  3144. parser->normalizeExpression($5, type_string, false);
  3145. $$.setExpr(createExprAttribute(namespaceAtom, $3.getExpr(), $5.getExpr()));
  3146. $$.setPosition($1);
  3147. }
  3148. | RESPONSE '(' NOTRIM ')'
  3149. {
  3150. $$.setExpr(createExprAttribute(responseAtom, createAttribute(noTrimAtom)), $1);
  3151. }
  3152. | commonAttribute
  3153. | TOK_LOG '(' MIN ')'
  3154. {
  3155. $$.setExpr(createExprAttribute(logAtom, createAttribute(minAtom)), $1);
  3156. }
  3157. | TOK_LOG '(' expression ')'
  3158. {
  3159. parser->normalizeExpression($3, type_string, false);
  3160. $$.setExpr(createExprAttribute(logAtom, $3.getExpr()), $1);
  3161. }
  3162. ;
  3163. onFailAction
  3164. : ONFAIL '(' SKIP ')'
  3165. {
  3166. $$.setExpr(createExprAttribute(onFailAtom, createValue(no_skip, makeVoidType())));
  3167. $$.setPosition($1);
  3168. }
  3169. | ONFAIL '(' transform ')'
  3170. {
  3171. $$.setExpr(createExprAttribute(onFailAtom, $3.getExpr()));
  3172. $$.setPosition($1);
  3173. }
  3174. ;
  3175. clusterAttr
  3176. : CLUSTER '(' stringExpressionList ')'
  3177. {
  3178. HqlExprArray args;
  3179. $3.unwindCommaList(args);
  3180. $$.setExpr(createExprAttribute(clusterAtom, args));
  3181. $$.setPosition($1);
  3182. }
  3183. ;
  3184. stringExpressionList
  3185. : expression
  3186. {
  3187. parser->normalizeExpression($1, type_string, false);
  3188. $$.inherit($1);
  3189. }
  3190. | stringExpressionList ',' expression
  3191. {
  3192. parser->normalizeExpression($3, type_string, false);
  3193. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  3194. $$.setPosition($1);
  3195. }
  3196. ;
  3197. expressionList
  3198. : expression
  3199. {
  3200. parser->normalizeExpression($1);
  3201. $$.inherit($1);
  3202. }
  3203. | expressionList ',' expression
  3204. {
  3205. parser->normalizeExpression($3);
  3206. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  3207. $$.setPosition($1);
  3208. }
  3209. ;
  3210. optOutputWuFlags
  3211. : { $$.setNullExpr(); $$.clearPosition(); }
  3212. | ',' outputWuFlags {
  3213. $$.setExpr($2.getExpr());
  3214. $$.setPosition($1);
  3215. }
  3216. ;
  3217. outputWuFlags
  3218. : outputWuFlag
  3219. | outputWuFlags ',' outputWuFlag
  3220. {
  3221. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  3222. $$.setPosition($1);
  3223. }
  3224. ;
  3225. outputWuFlag
  3226. : ALL {
  3227. $$.setExpr(createAttribute(allAtom));
  3228. $$.setPosition($1);
  3229. }
  3230. | FIRST '(' constExpression ')'
  3231. {
  3232. parser->normalizeExpression($3, type_int, true);
  3233. $$.setExpr(createAttribute(firstAtom, $3.getExpr()));
  3234. $$.setPosition($1);
  3235. }
  3236. | THOR {
  3237. $$.setExpr(createAttribute(diskAtom));
  3238. $$.setPosition($1);
  3239. }
  3240. | NAMED '(' constExpression ')'
  3241. {
  3242. parser->normalizeStoredNameExpression($3);
  3243. $$.setExpr(createAttribute(namedAtom, $3.getExpr()));
  3244. $$.setPosition($1);
  3245. }
  3246. | STORED {
  3247. $$.setExpr(createAttribute(workunitAtom)); // need a better keyword, but WORKUNIT is no good
  3248. $$.setPosition($1);
  3249. }
  3250. | EXTEND {
  3251. $$.setExpr(createAttribute(extendAtom));
  3252. $$.setPosition($1);
  3253. }
  3254. | OVERWRITE {
  3255. $$.setExpr(createAttribute(overwriteAtom));
  3256. $$.setPosition($1);
  3257. }
  3258. | NOOVERWRITE {
  3259. $$.setExpr(createAttribute(noOverwriteAtom));
  3260. $$.setPosition($1);
  3261. }
  3262. | UPDATE {
  3263. $$.setExpr(createComma(createAttribute(updateAtom), createAttribute(overwriteAtom)));
  3264. $$.setPosition($1);
  3265. }
  3266. | NOXPATH {
  3267. $$.setExpr(createAttribute(noXpathAtom));
  3268. $$.setPosition($1);
  3269. }
  3270. | commonAttribute
  3271. | MAXSIZE '(' constExpression ')'
  3272. {
  3273. parser->normalizeExpression($3, type_int, false);
  3274. $$.setExpr(createExprAttribute(maxSizeAtom, $3.getExpr()));
  3275. $$.setPosition($1);
  3276. }
  3277. ;
  3278. optCommaTrim
  3279. : { $$.setExpr(NULL); }
  3280. | ',' TRIM {
  3281. $$.setExpr(createAttribute(trimAtom), $1);
  3282. }
  3283. ;
  3284. applyActions
  3285. : action
  3286. | applyActions',' applyOption
  3287. {
  3288. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  3289. $$.setPosition($1);
  3290. }
  3291. ;
  3292. applyOption
  3293. : BEFORE '(' beginList actionlist ')'
  3294. {
  3295. HqlExprArray actions;
  3296. parser->endList(actions);
  3297. $$.setExpr(createExprAttribute(beforeAtom, createActionList(actions)));
  3298. $$.setPosition($1);
  3299. }
  3300. | AFTER '(' beginList actionlist ')'
  3301. {
  3302. HqlExprArray actions;
  3303. parser->endList(actions);
  3304. $$.setExpr(createExprAttribute(afterAtom, createActionList(actions)));
  3305. $$.setPosition($1);
  3306. }
  3307. | action
  3308. ;
  3309. keyDiffFlags
  3310. : { $$.setNullExpr(); $$.clearPosition(); }
  3311. | keyDiffFlags ',' keyDiffFlag
  3312. {
  3313. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  3314. $$.setPosition($1);
  3315. }
  3316. ;
  3317. keyDiffFlag
  3318. : OVERWRITE {
  3319. $$.setExpr(createAttribute(overwriteAtom));
  3320. $$.setPosition($1);
  3321. }
  3322. | NOOVERWRITE {
  3323. $$.setExpr(createAttribute(noOverwriteAtom));
  3324. $$.setPosition($1);
  3325. }
  3326. | expireAttr
  3327. | commonAttribute
  3328. ;
  3329. optRecordDef
  3330. : recordDef
  3331. | {
  3332. $$.setExpr(createValue(no_null));
  3333. $$.clearPosition();
  3334. }
  3335. ;
  3336. scopedActionId
  3337. : ACTION_ID
  3338. | moduleScopeDot ACTION_ID leaveScope
  3339. {
  3340. $1.release();
  3341. $$.setExpr($2.getExpr());
  3342. $$.setPosition($2);
  3343. }
  3344. | actionFunction '('
  3345. {
  3346. parser->beginFunctionCall($1);
  3347. }
  3348. actualParameters ')'
  3349. {
  3350. $$.setExpr(parser->bindParameters($1, $4.getExpr()));
  3351. $$.setPosition($1);
  3352. }
  3353. | VALUE_MACRO action ENDMACRO
  3354. {
  3355. $$.setExpr($2.getExpr());
  3356. $$.setPosition($1);
  3357. }
  3358. | moduleScopeDot VALUE_MACRO leaveScope action ENDMACRO
  3359. {
  3360. $1.release();
  3361. $$.setExpr($4.getExpr());
  3362. $$.setPosition($2);
  3363. }
  3364. ;
  3365. eventObject
  3366. : EVENT '(' expression ',' expression ')'
  3367. {
  3368. parser->normalizeExpression($3, type_string, false);
  3369. parser->normalizeExpression($5, type_string, false);
  3370. $$.setExpr(createValue(no_event, makeEventType(), $3.getExpr(), $5.getExpr()));
  3371. $$.setPosition($1);
  3372. }
  3373. | CRON '(' expression ')'
  3374. {
  3375. parser->normalizeExpression($3, type_string, true);
  3376. $$.setExpr(createValue(no_event, makeEventType(), createConstant("CRON"), $3.getExpr()));
  3377. $$.setPosition($1);
  3378. }
  3379. | EVENT_ID
  3380. | moduleScopeDot EVENT_ID leaveScope
  3381. {
  3382. $1.release();
  3383. $$.setExpr($2.getExpr());
  3384. $$.setPosition($2);
  3385. }
  3386. | eventFunction '('
  3387. {
  3388. parser->beginFunctionCall($1);
  3389. }
  3390. actualParameters ')'
  3391. {
  3392. $$.setExpr(parser->bindParameters($1, $4.getExpr()));
  3393. $$.setPosition($1);
  3394. }
  3395. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN eventObject ';' endInlineFunctionToken
  3396. {
  3397. Owned<ITypeInfo> retType = $1.getType();
  3398. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  3399. }
  3400. ;
  3401. event
  3402. : eventObject
  3403. | expression {
  3404. parser->normalizeExpression($1, type_string, true);
  3405. $$.setExpr(createValue(no_event, makeEventType(), $1.getExpr()));
  3406. $$.setPosition($1);
  3407. }
  3408. ;
  3409. parmdef
  3410. : realparmdef { parser->setParametered(true); $$.clear(); }
  3411. | { parser->setParametered(false); $$.clear(); }
  3412. ;
  3413. reqparmdef
  3414. : realparmdef { parser->setParametered(true); $$.clear(); }
  3415. ;
  3416. realparmdef
  3417. : '(' params ')'
  3418. | '(' ')'
  3419. ;
  3420. params
  3421. : param
  3422. | params ',' param
  3423. ;
  3424. // NB: the beginList is processed in the addParameter calls
  3425. //Also duplicating the line rather than having formalQualifiers have a null entry allows the canFollowCurrentState() function to work better
  3426. param
  3427. : beginList paramDefinition
  3428. | beginList formalQualifiers paramDefinition
  3429. ;
  3430. formalQualifiers
  3431. : formalQualifier
  3432. {
  3433. parser->addListElement($1.getExpr());
  3434. $$.clear();
  3435. }
  3436. | formalQualifiers formalQualifier
  3437. {
  3438. parser->addListElement($2.getExpr());
  3439. $$.clear();
  3440. }
  3441. ;
  3442. formalQualifier
  3443. : TOK_CONST { $$.setExpr(createAttribute(constAtom), $1); }
  3444. | TOK_ASSERT TOK_CONST
  3445. { $$.setExpr(createAttribute(assertConstAtom), $1); }
  3446. | FIELD_REF {
  3447. parser->setTemplateAttribute();
  3448. $$.setExpr(createAttribute(fieldAtom), $1);
  3449. }
  3450. | FIELDS_REF {
  3451. parser->setTemplateAttribute();
  3452. $$.setExpr(createAttribute(fieldsAtom), $1);
  3453. }
  3454. | OPT { $$.setExpr(createAttribute(optAtom), $1); }
  3455. | TOK_OUT { $$.setExpr(createAttribute(outAtom), $1); }
  3456. ;
  3457. paramDefinition
  3458. : setType knownOrUnknownId defvalue
  3459. {
  3460. $$.clear();
  3461. parser->addParameter($1, $2.getId(), $1.getType(), $3.getExpr());
  3462. }
  3463. | paramType knownOrUnknownId defvalue
  3464. {
  3465. $$.clear();
  3466. parser->addParameter($1, $2.getId(), $1.getType(), $3.getExpr());
  3467. }
  3468. | UNKNOWN_ID defvalue
  3469. {
  3470. $$.clear();
  3471. parser->addListElement(createAttribute(noTypeAtom));
  3472. parser->addParameter($1, $1.getId(), LINK(parser->defaultIntegralType), $2.getExpr());
  3473. }
  3474. | anyFunction defvalue
  3475. {
  3476. //So that new action format doesn't break existing code.
  3477. $$.clear();
  3478. parser->addListElement(createAttribute(noTypeAtom));
  3479. OwnedHqlExpr func = $1.getExpr();
  3480. parser->addParameter($1, func->queryId(), LINK(parser->defaultIntegralType), $2.getExpr());
  3481. }
  3482. | ANY DATASET knownOrUnknownId
  3483. {
  3484. $$.clear();
  3485. parser->addParameter($1, $3.getId(), makeTableType(makeRowType(queryNullRecord()->getType())), NULL);
  3486. }
  3487. | ANY knownOrUnknownId defvalue
  3488. {
  3489. $$.clear();
  3490. parser->setTemplateAttribute();
  3491. parser->addParameter($1, $2.getId(), makeAnyType(), $3.getExpr());
  3492. }
  3493. | paramType knownOrUnknownId nestedParmdef defFuncValue
  3494. {
  3495. $$.clear();
  3496. parser->addFunctionParameter($1, $2.getId(), $1.getType(), $4.getExpr());
  3497. }
  3498. | setType knownOrUnknownId nestedParmdef defFuncValue
  3499. {
  3500. $$.clear();
  3501. parser->addFunctionParameter($1, $2.getId(), $1.getType(), $4.getExpr());
  3502. }
  3503. // Use a function as a prototype for the argument type - kind of a substitute for a typedef
  3504. | anyFunction UNKNOWN_ID defFuncValue
  3505. {
  3506. $$.clear();
  3507. parser->addFunctionProtoParameter($1, $2.getId(), $1.getExpr(), $3.getExpr());
  3508. }
  3509. ;
  3510. nestedParmdef
  3511. : beginNestedParamDef params ')'
  3512. | beginNestedParamDef ')'
  3513. ;
  3514. beginNestedParamDef
  3515. : '(' {
  3516. parser->enterScope(true);
  3517. parser->setParametered(true);
  3518. $$.clear();
  3519. } // Enter type to save parameters
  3520. ;
  3521. defvalue
  3522. : EQ expression
  3523. {
  3524. parser->normalizeExpression($2);
  3525. $$.inherit($2);
  3526. }
  3527. | EQ dataSet { $$.inherit($2); }
  3528. | EQ dataRow { $$.inherit($2); }
  3529. | EQ abstractModule
  3530. {
  3531. $$.inherit($2);
  3532. }
  3533. | { $$.setNullExpr(); }
  3534. ;
  3535. defFuncValue
  3536. : { $$.setNullExpr(); }
  3537. | EQ anyFunction { $$.setExpr($2.getExpr()); }
  3538. ;
  3539. service
  3540. : startService funcDefs END
  3541. {
  3542. $$.setExpr(parser->leaveService($3), $1);
  3543. }
  3544. | startService error
  3545. {
  3546. $$.setExpr(parser->leaveService($2), $1);
  3547. }
  3548. ;
  3549. startService
  3550. : SERVICE attribs
  3551. {
  3552. parser->enterService($2);
  3553. $$.clear();
  3554. }
  3555. ;
  3556. funcDefs
  3557. : funcDef
  3558. | funcDefs funcDef
  3559. ;
  3560. funcDef
  3561. : funcRetType knownOrUnknownId realparmdef attribs ';'
  3562. {
  3563. $$.clear($1);
  3564. IIdAtom * name = $2.getId();
  3565. OwnedITypeInfo type = $1.getType();
  3566. OwnedHqlExpr attrs = $4.getExpr();
  3567. parser->processServiceFunction($2, name, attrs, type);
  3568. }
  3569. | knownOrUnknownId realparmdef attribs ';'
  3570. {
  3571. $$.clear($1);
  3572. IIdAtom * name = $1.getId();
  3573. OwnedITypeInfo type = makeVoidType();
  3574. OwnedHqlExpr attrs = $3.getExpr();
  3575. parser->processServiceFunction($1, name, attrs, type);
  3576. }
  3577. ;
  3578. attribs
  3579. : ':' attriblist { $$.setExpr($2.getExpr()); }
  3580. | { $$.setNullExpr(); }
  3581. ;
  3582. attriblist
  3583. : attrib
  3584. | attriblist ',' attrib
  3585. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  3586. ;
  3587. attrib
  3588. : knownOrUnknownId EQ UNKNOWN_ID
  3589. {
  3590. parser->reportWarning(WRN_OBSOLETED_SYNTAX,$1.pos,"Syntax obsoleted; use alternative: id = '<string constant>'");
  3591. $$.setExpr(createAttribute($1.getId()->lower(), createConstant(*$3.getId())));
  3592. }
  3593. | knownOrUnknownId EQ expr %prec reduceAttrib
  3594. {
  3595. //NOTE %prec is there to prevent a s/r error from the "SERVICE : attrib" production
  3596. $$.setExpr(createExprAttribute($1.getId()->lower(), $3.getExpr()), $1);
  3597. }
  3598. | knownOrUnknownId
  3599. { $$.setExpr(createAttribute($1.getId()->lower())); }
  3600. | knownOrUnknownId '(' expr ')'
  3601. {
  3602. $$.setExpr(createExprAttribute($1.getId()->lower(), $3.getExpr()), $1);
  3603. }
  3604. | knownOrUnknownId '(' expr ',' expr ')'
  3605. {
  3606. $$.setExpr(createExprAttribute($1.getId()->lower(), $3.getExpr(), $5.getExpr()), $1);
  3607. }
  3608. ;
  3609. funcRetType
  3610. : TOK_CONST propType
  3611. {
  3612. $$.setType(makeConstantModifier($2.getType()));
  3613. $$.setPosition($1);
  3614. }
  3615. | propType
  3616. | setType
  3617. | explicitDatasetType
  3618. | explicitRowType
  3619. | explicitDictionaryType
  3620. | transformType
  3621. // A plain record would be better, but that then causes a s/r error in knownOrUnknownId because scope
  3622. | recordDef {
  3623. OwnedHqlExpr expr = $1.getExpr();
  3624. // $$.setType(makeOriginalModifier(makeRowType(expr->getType()), LINK(expr)));
  3625. $$.setType(makeRowType(expr->getType()));
  3626. $$.setPosition($1);
  3627. }
  3628. ;
  3629. payloadPart
  3630. : {
  3631. // NOTE - this reduction happens as soon as the GOESTO is seen,
  3632. // so it ensures that the following fields go into the payload record def
  3633. $$.setExpr(parser->endRecordDef());
  3634. parser->beginRecord();
  3635. }
  3636. GOESTO fieldDefs optSemiComma
  3637. ;
  3638. recordDef
  3639. : startrecord fieldDefs optSemiComma endrecord
  3640. {
  3641. OwnedHqlExpr record = $4.getExpr();
  3642. parser->checkRecordIsValid($1, record);
  3643. $$.setExpr(record.getClear(), $1);
  3644. }
  3645. | startrecord fieldDefs payloadPart endrecord
  3646. {
  3647. OwnedHqlExpr record = $3.getExpr();
  3648. OwnedHqlExpr payload = $4.getExpr();
  3649. parser->mergeDictionaryPayload(record, payload, $1);
  3650. $$.setExpr(record.getClear(), $1);
  3651. }
  3652. | startrecord recordOptions fieldDefs optSemiComma endrecord
  3653. {
  3654. OwnedHqlExpr record = $5.getExpr();
  3655. parser->checkRecordIsValid($1, record);
  3656. $$.setExpr(record.getClear(), $1);
  3657. }
  3658. | startrecord recordOptions fieldDefs payloadPart endrecord
  3659. {
  3660. OwnedHqlExpr record = $4.getExpr();
  3661. OwnedHqlExpr payload = $5.getExpr();
  3662. parser->mergeDictionaryPayload(record, payload, $1);
  3663. $$.setExpr(record.getClear(), $1);
  3664. }
  3665. | startrecord recordBase optFieldDefs endrecord
  3666. {
  3667. OwnedHqlExpr record = $4.getExpr();
  3668. parser->checkRecordIsValid($1, record);
  3669. $$.setExpr(record.getClear(), $1);
  3670. }
  3671. | startrecord recordBase optFieldDefs payloadPart endrecord
  3672. {
  3673. OwnedHqlExpr record = $4.getExpr();
  3674. OwnedHqlExpr payload = $5.getExpr();
  3675. parser->mergeDictionaryPayload(record, payload, $1);
  3676. $$.setExpr(record.getClear(), $1);
  3677. }
  3678. | startrecord recordBase recordOptions optFieldDefs endrecord
  3679. {
  3680. OwnedHqlExpr record = $5.getExpr();
  3681. parser->checkRecordIsValid($1, record);
  3682. $$.setExpr(record.getClear(), $1);
  3683. }
  3684. | startrecord recordBase recordOptions optFieldDefs payloadPart endrecord
  3685. {
  3686. OwnedHqlExpr record = $5.getExpr();
  3687. OwnedHqlExpr payload = $6.getExpr();
  3688. parser->mergeDictionaryPayload(record, payload, $1);
  3689. $$.setExpr(record.getClear(), $1);
  3690. }
  3691. | simpleRecord
  3692. | recordDef AND recordDef
  3693. {
  3694. OwnedHqlExpr left = $1.getExpr();
  3695. OwnedHqlExpr right = $3.getExpr();
  3696. $$.setExpr(parser->createRecordIntersection(left, right, $1));
  3697. $$.setPosition($1);
  3698. parser->checkRecordIsValid($1, $$.queryExpr());
  3699. }
  3700. | recordDef OR recordDef
  3701. {
  3702. OwnedHqlExpr left = $1.getExpr();
  3703. OwnedHqlExpr right = $3.getExpr();
  3704. $$.setExpr(parser->createRecordUnion(left, right, $1));
  3705. $$.setPosition($1);
  3706. }
  3707. | recordDef '-' recordDef
  3708. {
  3709. OwnedHqlExpr left = $1.getExpr();
  3710. OwnedHqlExpr right = $3.getExpr();
  3711. $$.setExpr(parser->createRecordDifference(left, right, $1));
  3712. $$.setPosition($1);
  3713. parser->checkRecordIsValid($1, $$.queryExpr());
  3714. }
  3715. | recordDef '-' UNKNOWN_ID
  3716. {
  3717. OwnedHqlExpr left = $1.getExpr();
  3718. OwnedHqlExpr right = createId($3.getId());
  3719. $$.setExpr(parser->createRecordExcept(left, right, $1));
  3720. $$.setPosition($1);
  3721. parser->checkRecordIsValid($1, $$.queryExpr());
  3722. }
  3723. | recordDef '-' '[' UnknownIdList ']'
  3724. {
  3725. OwnedHqlExpr left = $1.getExpr();
  3726. OwnedHqlExpr right = $4.getExpr();
  3727. $$.setExpr(parser->createRecordExcept(left, right, $1));
  3728. $$.setPosition($1);
  3729. parser->checkRecordIsValid($1, $$.queryExpr());
  3730. }
  3731. | recordDef AND NOT recordDef
  3732. {
  3733. OwnedHqlExpr left = $1.getExpr();
  3734. OwnedHqlExpr right = $4.getExpr();
  3735. $$.setExpr(parser->createRecordDifference(left, right, $1));
  3736. $$.setPosition($1);
  3737. parser->checkRecordIsValid($1, $$.queryExpr());
  3738. }
  3739. | recordDef AND NOT UNKNOWN_ID
  3740. {
  3741. OwnedHqlExpr left = $1.getExpr();
  3742. OwnedHqlExpr right = createId($4.getId());
  3743. $$.setExpr(parser->createRecordExcept(left, right, $1));
  3744. $$.setPosition($1);
  3745. parser->checkRecordIsValid($1, $$.queryExpr());
  3746. }
  3747. | recordDef AND NOT '[' UnknownIdList ']'
  3748. {
  3749. OwnedHqlExpr left = $1.getExpr();
  3750. OwnedHqlExpr right = $5.getExpr();
  3751. $$.setExpr(parser->createRecordExcept(left, right, $1));
  3752. $$.setPosition($1);
  3753. parser->checkRecordIsValid($1, $$.queryExpr());
  3754. }
  3755. | RECORDOF '(' goodObject ')'
  3756. {
  3757. OwnedHqlExpr ds = $3.getExpr();
  3758. IHqlExpression * record = queryOriginalRecord(ds);
  3759. if (!record)
  3760. {
  3761. parser->reportError(ERR_EXPECTED, $3, "The argument does not have a associated record");
  3762. record = queryNullRecord();
  3763. }
  3764. else if (ds->isFunction() && !record->isFullyBound())
  3765. parser->reportError(ERR_EXPECTED, $1, "RECORDOF(function-definition), result record depends on the function parameters");
  3766. $$.setExpr(LINK(record));
  3767. $$.setPosition($1);
  3768. }
  3769. | VALUE_MACRO recordDef ENDMACRO
  3770. {
  3771. $$.setExpr($2.getExpr());
  3772. $$.setPosition($1);
  3773. }
  3774. | moduleScopeDot VALUE_MACRO leaveScope recordDef ENDMACRO
  3775. {
  3776. $1.release();
  3777. $$.setExpr($4.getExpr());
  3778. $$.setPosition($2);
  3779. }
  3780. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN recordDef ';' endInlineFunctionToken
  3781. {
  3782. Owned<ITypeInfo> retType = $1.getType();
  3783. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  3784. }
  3785. ;
  3786. dsRecordDef
  3787. : recordDef {
  3788. IHqlExpression *r = $1.getExpr();
  3789. parser->pushSelfScope(LINK(r));
  3790. $$.setExpr(r);
  3791. $$.setPosition($1);
  3792. }
  3793. ;
  3794. dsEnd
  3795. : ')' {
  3796. parser->popSelfScope();
  3797. $$.clear();
  3798. $$.setPosition($1);
  3799. }
  3800. ;
  3801. UnknownIdList
  3802. : UNKNOWN_ID {
  3803. $$.setExpr(createId($1.getId()));
  3804. $$.setPosition($1);
  3805. }
  3806. | UnknownIdList ',' UNKNOWN_ID
  3807. {
  3808. $$.setExpr(createComma($1.getExpr(), createId($3.getId())));
  3809. $$.setPosition($1);
  3810. }
  3811. ;
  3812. //This needs to be in a separate production because of the side-effects, but that prevents
  3813. startrecord
  3814. : RECORD {
  3815. parser->beginRecord();
  3816. $$.clear();
  3817. }
  3818. | '{' {
  3819. parser->beginRecord();
  3820. $$.clear();
  3821. }
  3822. ;
  3823. recordBase
  3824. : '(' recordDef ')'
  3825. {
  3826. //MORE: May want to add this after all attributes.
  3827. OwnedHqlExpr base = $2.getExpr();
  3828. parser->activeRecords.tos().addOperand(LINK(base->queryBody()));
  3829. $$.clear();
  3830. }
  3831. ;
  3832. recordOptions
  3833. : ',' recordOption
  3834. {
  3835. parser->addRecordOption($2);
  3836. $$.clear($1);
  3837. }
  3838. | recordOptions ',' recordOption
  3839. {
  3840. parser->addRecordOption($3);
  3841. $$.clear($1);
  3842. }
  3843. ;
  3844. recordOption
  3845. : LOCALE '(' STRING_CONST ')'
  3846. {
  3847. OwnedHqlExpr lExpr = $3.getExpr();
  3848. StringBuffer lstr;
  3849. getStringValue(lstr, lExpr);
  3850. StringBuffer locale;
  3851. if(!getNormalizedLocaleName(lstr.length(), lstr.str(), locale))
  3852. parser->reportError(ERR_BAD_LOCALE, $3, "Bad locale name");
  3853. $$.setExpr(createAttribute(localeAtom, createConstant(locale.str())));
  3854. $$.setPosition($1);
  3855. }
  3856. | MAXLENGTH '(' constExpression ')'
  3857. {
  3858. parser->normalizeExpression($3, type_numeric, false);
  3859. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  3860. $$.setPosition($1);
  3861. }
  3862. | MAXSIZE '(' constExpression ')'
  3863. {
  3864. parser->normalizeExpression($3, type_numeric, false);
  3865. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  3866. $$.setPosition($1);
  3867. }
  3868. | PACKED
  3869. {
  3870. $$.setExpr(createAttribute(packedAtom));
  3871. $$.setPosition($1);
  3872. }
  3873. ;
  3874. endrecord
  3875. : endOfRecordMarker
  3876. {
  3877. $$.setExpr(parser->endRecordDef());
  3878. parser->popLocale();
  3879. $$.setPosition($1);
  3880. }
  3881. ;
  3882. endOfRecordMarker
  3883. : END
  3884. | '}'
  3885. ;
  3886. abstractDataset
  3887. : VIRTUAL DATASET '(' recordDef ')'
  3888. {
  3889. $$.setExpr($4.getExpr(), $1);
  3890. }
  3891. | VIRTUAL DATASET {
  3892. $$.setExpr(LINK(queryNullRecord()), $1);
  3893. }
  3894. ;
  3895. optSemiComma
  3896. : semiComma
  3897. |
  3898. ;
  3899. optFieldDefs
  3900. :
  3901. | fieldDefs
  3902. | fieldDefs ';'
  3903. | fieldDefs ','
  3904. ;
  3905. fieldDefs
  3906. : fieldDef
  3907. | fieldDefs ';' fieldDef
  3908. | fieldDefs ',' fieldDef
  3909. ;
  3910. fieldDef
  3911. : expression {
  3912. parser->normalizeExpression($1);
  3913. IHqlExpression *value = $1.getExpr();
  3914. IIdAtom * name = parser->createFieldNameFromExpr(value);
  3915. IHqlExpression * attrs = extractAttrsFromExpr(value);
  3916. ITypeInfo * type = value->queryType();
  3917. parser->addField($1, name, LINK(type), value, attrs);
  3918. $$.clear();
  3919. }
  3920. | VALUE_ID_REF {
  3921. OwnedHqlExpr value = $1.getExpr();
  3922. IHqlExpression * field = queryFieldFromExpr(value);
  3923. if (field && (field->getOperator() == no_field))
  3924. {
  3925. //The following adds the field instead of creating a new field based on the old one.
  3926. //More efficient, but changes a few CRCs, so disabled for moment.
  3927. parser->checkFieldnameValid($1, field->queryId());
  3928. parser->addToActiveRecord(LINK(field));
  3929. }
  3930. else
  3931. {
  3932. IIdAtom * name = parser->createFieldNameFromExpr(value);
  3933. IHqlExpression * attrs = extractAttrsFromExpr(value);
  3934. parser->addField($1, name, value->getType(), NULL, attrs);
  3935. }
  3936. $$.clear();
  3937. }
  3938. | fieldSelectedFromRecord
  3939. {
  3940. OwnedHqlExpr value = $1.getExpr();
  3941. if (false)
  3942. {
  3943. //The following adds the field instead of creating a new field based on the old one.
  3944. //More efficient, but changes a few CRCs, so disabled for moment.
  3945. IHqlExpression * field = queryFieldFromSelect(value);
  3946. parser->checkFieldnameValid($1, field->queryId());
  3947. parser->addToActiveRecord(LINK(field));
  3948. }
  3949. else
  3950. {
  3951. IIdAtom * name = parser->createFieldNameFromExpr(value);
  3952. IHqlExpression * attrs = extractAttrsFromExpr(value);
  3953. parser->addField($1, name, value->getType(), NULL, attrs);
  3954. }
  3955. $$.clear();
  3956. }
  3957. | UNKNOWN_ID optFieldAttrs ASSIGN expression
  3958. {
  3959. parser->normalizeExpression($4);
  3960. $$.clear($1);
  3961. // NOTE - you might expect the default value to be optional, to declare an integer....
  3962. // But that might be too error-prone
  3963. IHqlExpression *value = $4.getExpr();
  3964. IHqlExpression *attrs = $2.getExpr();
  3965. if (!attrs)
  3966. attrs = extractAttrsFromExpr(value);
  3967. parser->addField($1, $1.getId(), value->getType(), value, attrs);
  3968. $$.clear();
  3969. }
  3970. | UNKNOWN_ID optFieldAttrs ASSIGN dataRow
  3971. {
  3972. IHqlExpression *value = $4.getExpr();
  3973. IHqlExpression *attrs = $2.getExpr();
  3974. if (!attrs)
  3975. attrs = extractAttrsFromExpr(value);
  3976. parser->addField($1, $1.getId(), makeRowType(LINK(value->queryRecordType())), value, attrs);
  3977. $$.clear();
  3978. }
  3979. | typeDef knownOrUnknownId optFieldAttrs defaultValue
  3980. {
  3981. $$.clear($1);
  3982. IHqlExpression *value = $4.getExpr();
  3983. //Syntactic oddity. A record means a row of that record type.
  3984. OwnedITypeInfo type = $1.getType();
  3985. if (type->getTypeCode() == type_record)
  3986. type.setown(makeRowType(type.getClear()));
  3987. parser->addField($2, $2.getId(), type.getClear(), value, $3.getExpr());
  3988. }
  3989. | ANY knownOrUnknownId optFieldAttrs defaultValue
  3990. {
  3991. $$.clear($1);
  3992. IHqlExpression *value = $4.getExpr();
  3993. //Syntactic oddity. A record means a row of that record type.
  3994. OwnedITypeInfo type = makeAnyType();
  3995. parser->addField($2, $2.getId(), type.getClear(), value, $3.getExpr());
  3996. }
  3997. | typeDef knownOrUnknownId '[' expression ']' optFieldAttrs defaultValue
  3998. {
  3999. $$.clear($1);
  4000. parser->normalizeExpression($4, type_int, false);
  4001. OwnedHqlExpr attrs = $6.getExpr();
  4002. OwnedITypeInfo type = $1.getType();
  4003. IHqlExpression * record = queryNullRecord();
  4004. if (type->getTypeCode() != type_record)
  4005. parser->reportError(WRN_UNSUPPORTED_FEATURE, $3, "Only arrays of records are supported");
  4006. else
  4007. {
  4008. record = queryOriginalRecord(type);
  4009. attrs.setown(createComma(createLinkAttribute(countAtom, $4.getExpr()), attrs.getClear()));
  4010. }
  4011. IHqlExpression *value = $7.getExpr();
  4012. Owned<ITypeInfo> datasetType = makeTableType(makeRowType(createRecordType(record)));
  4013. parser->addDatasetField($2, $2.getId(), datasetType, value, attrs.getClear());
  4014. }
  4015. | setType knownOrUnknownId optFieldAttrs defaultValue
  4016. {
  4017. $$.clear($1);
  4018. IHqlExpression *value = $4.getExpr();
  4019. ITypeInfo *type = $1.getType();
  4020. parser->addField($2, $2.getId(), type, value, $3.getExpr());
  4021. }
  4022. | explicitDatasetType knownOrUnknownId optFieldAttrs defaultValue
  4023. {
  4024. $$.clear($1);
  4025. Owned<ITypeInfo> type = $1.getType();
  4026. parser->addDatasetField($2, $2.getId(), type, $4.getExpr(), $3.getExpr());
  4027. }
  4028. | UNKNOWN_ID optFieldAttrs ASSIGN dataSet
  4029. {
  4030. IHqlExpression * value = $4.getExpr();
  4031. parser->addDatasetField($1, $1.getId(), NULL, value, $2.getExpr());
  4032. $$.clear();
  4033. }
  4034. | explicitDictionaryType knownOrUnknownId optFieldAttrs defaultValue
  4035. {
  4036. $$.clear($1);
  4037. Owned<ITypeInfo> type = $1.getType();
  4038. parser->addDictionaryField($2, $2.getId(), type, $4.getExpr(), $3.getExpr());
  4039. }
  4040. | UNKNOWN_ID optFieldAttrs ASSIGN dictionary
  4041. {
  4042. IHqlExpression * value = $4.getExpr();
  4043. parser->addDictionaryField($1, $1.getId(), value->queryType(), value, $2.getExpr());
  4044. $$.clear();
  4045. }
  4046. | alienTypeInstance knownOrUnknownId optFieldAttrs defaultValue
  4047. {
  4048. $$.clear($1);
  4049. parser->addField($2, $2.getId(), $1.getType(), $4.getExpr(), $3.getExpr());
  4050. }
  4051. | recordDef {
  4052. //This distinguish between an inline record definition, and an out-of-line definition
  4053. //The inline shouldn't clone, but should just add the fields from the record.
  4054. OwnedHqlExpr e = $1.getExpr();
  4055. parser->addFields($1, e, NULL, hasNamedSymbol(e));
  4056. $$.clear();
  4057. }
  4058. | dictionary {
  4059. parser->normalizeExpression($1);
  4060. IHqlExpression *value = $1.getExpr();
  4061. IIdAtom * name = parser->createFieldNameFromExpr(value);
  4062. IHqlExpression * attrs = extractAttrsFromExpr(value);
  4063. ITypeInfo * type = value->queryType();
  4064. parser->addField($1, name, LINK(type), value, attrs);
  4065. $$.clear();
  4066. }
  4067. | dataSet {
  4068. OwnedHqlExpr e = $1.getExpr();
  4069. parser->addFields($1, e->queryRecord(), e, true);
  4070. $$.clear();
  4071. }
  4072. | dataRow {
  4073. IHqlExpression *e = $1.getExpr();
  4074. IHqlExpression * attrs = extractAttrsFromExpr(e);
  4075. IIdAtom * name = parser->createFieldNameFromExpr(e);
  4076. parser->addField($1, name, makeRowType(LINK(e->queryRecordType())), e, attrs);
  4077. //e->Release();
  4078. $$.clear();
  4079. }
  4080. | ifblock
  4081. | error {
  4082. $$.clear();
  4083. }
  4084. | expandedSortListByReference
  4085. {
  4086. OwnedHqlExpr list = $1.getExpr();
  4087. if (list && (list->queryType()->getTypeCode() != type_sortlist))
  4088. {
  4089. HqlExprArray items;
  4090. list->unwindList(items, no_comma);
  4091. ForEachItemIn(i, items)
  4092. {
  4093. IHqlExpression * value = &items.item(i);
  4094. IIdAtom * name = parser->createFieldNameFromExpr(value);
  4095. IHqlExpression * attrs = extractAttrsFromExpr(value);
  4096. parser->addField($1, name, value->getType(), LINK(value), attrs);
  4097. }
  4098. }
  4099. $$.clear();
  4100. }
  4101. ;
  4102. optFieldAttrs
  4103. : { $$.setNullExpr(); }
  4104. | '{' '}' { $$.setNullExpr(); }
  4105. | '{' fieldAttrs '}'
  4106. { $$.setExpr($2.getExpr()); }
  4107. ;
  4108. fieldAttrs
  4109. : fieldAttr
  4110. | fieldAttr ',' fieldAttrs
  4111. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  4112. ;
  4113. fieldAttr
  4114. : BLOB
  4115. {
  4116. $$.setExpr(createAttribute(blobAtom));
  4117. }
  4118. | CARDINALITY '(' expression ')'
  4119. {
  4120. parser->normalizeExpression($3, type_numeric, false);
  4121. $$.setExpr(createExprAttribute(cardinalityAtom, $3.getExpr()));
  4122. }
  4123. | CASE '(' expression ')'
  4124. {
  4125. parser->normalizeExpression($3, type_set, false);
  4126. $$.setExpr(createExprAttribute(caseAtom, $3.getExpr()));
  4127. }
  4128. | MAXCOUNT '(' expression ')'
  4129. {
  4130. parser->normalizeExpression($3, type_int, true);
  4131. $$.setExpr(createExprAttribute(maxCountAtom, $3.getExpr()));
  4132. }
  4133. | CHOOSEN '(' expression ')'
  4134. {
  4135. parser->normalizeExpression($3, type_int, true);
  4136. $$.setExpr(createExprAttribute(choosenAtom, $3.getExpr()));
  4137. }
  4138. | MAXLENGTH '(' expression ')'
  4139. {
  4140. parser->normalizeExpression($3, type_int, true);
  4141. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  4142. }
  4143. | MAXSIZE '(' expression ')'
  4144. {
  4145. parser->normalizeExpression($3, type_int, true);
  4146. $$.setExpr(createExprAttribute(maxSizeAtom, $3.getExpr()));
  4147. }
  4148. | NAMED '(' expression ')'
  4149. {
  4150. parser->normalizeExpression($3, type_any, true);
  4151. $$.setExpr(createExprAttribute(namedAtom, $3.getExpr()));
  4152. }
  4153. | RANGE '(' rangeExpr ')'
  4154. {
  4155. $$.setExpr(createExprAttribute(rangeAtom, $3.getExpr()));
  4156. }
  4157. | VIRTUAL '(' LOGICALFILENAME ')'
  4158. {
  4159. $$.setExpr(createExprAttribute(virtualAtom, createAttribute(logicalFilenameAtom)));
  4160. }
  4161. | VIRTUAL '(' FILEPOSITION ')'
  4162. {
  4163. $$.setExpr(createExprAttribute(virtualAtom, createAttribute(filepositionAtom)));
  4164. }
  4165. | VIRTUAL '(' LOCALFILEPOSITION ')'
  4166. {
  4167. $$.setExpr(createExprAttribute(virtualAtom, createAttribute(localFilePositionAtom)));
  4168. }
  4169. | VIRTUAL '(' SIZEOF ')'
  4170. {
  4171. $$.setExpr(createExprAttribute(virtualAtom, createAttribute(sizeofAtom)));
  4172. }
  4173. | XPATH '(' constExpression ')'
  4174. {
  4175. parser->normalizeExpression($3, type_string, false);
  4176. parser->validateXPath($3);
  4177. $$.setExpr(createExprAttribute(xpathAtom, $3.getExpr()));
  4178. }
  4179. | XMLDEFAULT '(' constExpression ')'
  4180. {
  4181. $$.setExpr(createExprAttribute(xmlDefaultAtom, $3.getExpr()), $1);
  4182. }
  4183. | DEFAULT '(' constExpression ')'
  4184. {
  4185. $$.setExpr(createExprAttribute(defaultAtom, $3.getExpr()), $1);
  4186. }
  4187. | STRING_CONST
  4188. {
  4189. OwnedHqlExpr expr = $1.getExpr();
  4190. StringBuffer text;
  4191. getStringValue(text, expr);
  4192. $$.setExpr(createAttribute(createAtom(text.str())), $1);
  4193. }
  4194. | STRING_CONST '(' expression ')'
  4195. {
  4196. parser->normalizeExpression($3);
  4197. OwnedHqlExpr expr = $1.getExpr();
  4198. StringBuffer text;
  4199. getStringValue(text, expr);
  4200. $$.setExpr(createAttribute(createAtom(text), $3.getExpr()), $1);
  4201. }
  4202. | LINKCOUNTED
  4203. {
  4204. $$.setExpr(getLinkCountedAttr());
  4205. $$.setPosition($1);
  4206. }
  4207. | EMBEDDED
  4208. {
  4209. $$.setExpr(getEmbeddedAttr());
  4210. $$.setPosition($1);
  4211. }
  4212. ;
  4213. ifblock
  4214. : beginIfBlock fieldDefs optSemiComma END
  4215. {
  4216. IHqlExpression * record = parser->endIfBlock();
  4217. OwnedHqlExpr expr = createValue(no_ifblock, makeNullType(), $1.getExpr(), record);
  4218. parser->addIfBlockToActive($1, expr);
  4219. $$.clear();
  4220. }
  4221. | beginIfBlock optSemiComma END
  4222. {
  4223. parser->reportError(ERR_IFBLOCK_EMPTYDEF,$1,"Empty ifblock body");
  4224. ::Release(parser->endIfBlock());
  4225. $1.release();
  4226. $$.clear();
  4227. }
  4228. ;
  4229. beginIfBlock
  4230. : IFBLOCK '(' booleanExpr ')'
  4231. {
  4232. parser->beginIfBlock();
  4233. $$.setExpr($3.getExpr());
  4234. $$.setPosition($1);
  4235. }
  4236. ;
  4237. qualifiedTypeId
  4238. : ALIEN_ID
  4239. | moduleScopeDot ALIEN_ID leaveScope
  4240. {
  4241. $1.release();
  4242. $$.setExpr($2.getExpr());
  4243. $$.setPosition($2);
  4244. }
  4245. ;
  4246. enumTypeId
  4247. : ENUM_ID
  4248. | moduleScopeDot ENUM_ID leaveScope
  4249. {
  4250. $1.release();
  4251. $$.setExpr($2.getExpr());
  4252. $$.setPosition($2);
  4253. }
  4254. ;
  4255. optParams
  4256. : '(' actualParameters ')'
  4257. { $$.setExpr($2.getExpr()); }
  4258. | { $$.setNullExpr(); }
  4259. ;
  4260. defaultValue
  4261. : ASSIGN expression
  4262. {
  4263. parser->normalizeExpression($2);
  4264. $$.inherit($2);
  4265. }
  4266. | ASSIGN dataRow
  4267. {
  4268. $$.inherit($2);
  4269. }
  4270. | ASSIGN dataSet
  4271. {
  4272. $$.inherit($2);
  4273. }
  4274. | ASSIGN dictionary
  4275. {
  4276. $$.inherit($2);
  4277. }
  4278. | ASSIGN abstractModule
  4279. {
  4280. $$.inherit($2);
  4281. }
  4282. |
  4283. {
  4284. $$.setNullExpr();
  4285. }
  4286. ;
  4287. setType
  4288. : SET
  4289. {
  4290. $$.setType(makeSetType(LINK(parser->defaultIntegralType)));
  4291. }
  4292. | SET OF ANY
  4293. {
  4294. $$.setType(makeSetType(NULL));
  4295. }
  4296. | SET OF scalarType
  4297. {
  4298. $$.setType(makeSetType($3.getType()));
  4299. }
  4300. | SET OF explicitDatasetType
  4301. {
  4302. $$.setType(makeSetType($3.getType()));
  4303. }
  4304. | userTypedefSet
  4305. ;
  4306. simpleType
  4307. : SIMPLE_TYPE
  4308. | UNSIGNED {
  4309. $$.setType(makeIntType(8, false));
  4310. $$.setPosition($1);
  4311. }
  4312. | PACKED simpleType
  4313. {
  4314. ITypeInfo *type = $2.getType();
  4315. switch (type->getTypeCode())
  4316. {
  4317. case type_int:
  4318. $$.setType(makePackedIntType(type->getSize(), type->isSigned()));
  4319. type->Release();
  4320. break;
  4321. default:
  4322. parser->reportError(ERR_TYPEERR_INTDECIMAL, $2, "Integer type expected");
  4323. $$.setType(type);
  4324. break;
  4325. }
  4326. $$.setPosition($1);
  4327. }
  4328. | UNSIGNED SIMPLE_TYPE
  4329. {
  4330. ITypeInfo *type = $2.getType();
  4331. switch (type->getTypeCode())
  4332. {
  4333. case type_int:
  4334. $$.setType(makeIntType(type->getSize(), false));
  4335. type->Release();
  4336. break;
  4337. case type_swapint:
  4338. $$.setType(makeSwapIntType(type->getSize(), false));
  4339. type->Release();
  4340. break;
  4341. case type_packedint:
  4342. $$.setType(makePackedIntType(type->getSize(), false));
  4343. type->Release();
  4344. break;
  4345. case type_decimal:
  4346. $$.setType(makeDecimalType(type->getDigits(), type->getPrecision(), false));
  4347. type->Release();
  4348. break;
  4349. default:
  4350. parser->reportError(ERR_TYPEERR_INTDECIMAL, $2, "Integer or decimal type expected");
  4351. $$.setType(type);
  4352. break;
  4353. }
  4354. $$.setPosition($1);
  4355. }
  4356. | BIG simpleType {
  4357. ITypeInfo *type = $2.getType();
  4358. switch (type->getTypeCode())
  4359. {
  4360. case type_int:
  4361. #if __BYTE_ORDER == __LITTLE_ENDIAN
  4362. $$.setType(makeSwapIntType(type->getSize(), type->isSigned()));
  4363. type->Release();
  4364. #else
  4365. $$.setType(type);
  4366. #endif
  4367. break;
  4368. default:
  4369. parser->reportError(ERR_TYPEERR_INT, $2, "Integer type expected");
  4370. $$.setType(type);
  4371. break;
  4372. }
  4373. $$.setPosition($1);
  4374. }
  4375. | LITTLE simpleType {
  4376. ITypeInfo *type = $2.getType();
  4377. switch (type->getTypeCode())
  4378. {
  4379. case type_int:
  4380. #if __BYTE_ORDER == __LITTLE_ENDIAN
  4381. $$.setType(type);
  4382. #else
  4383. $$.setType(makeSwapIntType(type->getSize(), type->isSigned()));
  4384. type->Release();
  4385. #endif
  4386. break;
  4387. default:
  4388. parser->reportError(ERR_TYPEERR_INT, $2, "Integer type expected");
  4389. $$.setType(type);
  4390. break;
  4391. }
  4392. $$.setPosition($1);
  4393. }
  4394. | ASCII SIMPLE_TYPE {
  4395. Owned<ITypeInfo> type = $2.getType();
  4396. if (type->getTypeCode() != type_string)
  4397. parser->reportError(ERR_TYPEERR_STRING, $2, "String type expected");
  4398. $$.setType(makeStringType(type->getSize(), getCharset(asciiAtom), NULL));
  4399. $$.setPosition($1);
  4400. }
  4401. | EBCDIC SIMPLE_TYPE
  4402. {
  4403. Owned<ITypeInfo> type = $2.getType();
  4404. if (type->getTypeCode() != type_string)
  4405. parser->reportError(ERR_TYPEERR_STRING, $2, "String type expected");
  4406. $$.setType(makeStringType(type->getSize(), getCharset(ebcdicAtom), NULL));
  4407. $$.setPosition($1);
  4408. }
  4409. | TYPEOF '(' goodObject ')'
  4410. {
  4411. OwnedHqlExpr arg = $3.getExpr();
  4412. ITypeInfo *type = arg->getType();
  4413. if (!type)
  4414. {
  4415. parser->reportError(ERR_TYPEOF_ILLOPERAND, $3, "Illegal operand for TYPEOF");
  4416. type = LINK(parser->defaultIntegralType);
  4417. }
  4418. else
  4419. {
  4420. // type = preserveTypeQualifiers(type, arg);
  4421. }
  4422. $$.setType(type);
  4423. $$.setPosition($1);
  4424. }
  4425. ;
  4426. userTypedefType
  4427. : TYPE_ID {
  4428. OwnedHqlExpr typedefExpr = $1.getExpr();
  4429. $$.setType(getTypedefType(typedefExpr));
  4430. $$.setPosition($1);
  4431. }
  4432. | moduleScopeDot TYPE_ID leaveScope
  4433. {
  4434. $1.release();
  4435. OwnedHqlExpr typedefExpr = $2.getExpr();
  4436. $$.setType(getTypedefType(typedefExpr));
  4437. $$.setPosition($1);
  4438. }
  4439. ;
  4440. userTypedefSet
  4441. : SET_TYPE_ID {
  4442. OwnedHqlExpr typedefExpr = $1.getExpr();
  4443. $$.setType(getTypedefType(typedefExpr));
  4444. $$.setPosition($1);
  4445. }
  4446. | moduleScopeDot SET_TYPE_ID leaveScope
  4447. {
  4448. $1.release();
  4449. OwnedHqlExpr typedefExpr = $2.getExpr();
  4450. $$.setType(getTypedefType(typedefExpr));
  4451. $$.setPosition($1);
  4452. }
  4453. ;
  4454. userTypedefPattern
  4455. : PATTERN_TYPE_ID {
  4456. OwnedHqlExpr typedefExpr = $1.getExpr();
  4457. $$.setType(getTypedefType(typedefExpr));
  4458. $$.setPosition($1);
  4459. }
  4460. | moduleScopeDot PATTERN_TYPE_ID leaveScope
  4461. {
  4462. $1.release();
  4463. OwnedHqlExpr typedefExpr = $2.getExpr();
  4464. $$.setType(getTypedefType(typedefExpr));
  4465. $$.setPosition($1);
  4466. }
  4467. ;
  4468. userTypedefDataset
  4469. : DATASET_TYPE_ID {
  4470. OwnedHqlExpr typedefExpr = $1.getExpr();
  4471. $$.setType(getTypedefType(typedefExpr));
  4472. $$.setPosition($1);
  4473. }
  4474. | moduleScopeDot DATASET_TYPE_ID leaveScope
  4475. {
  4476. $1.release();
  4477. OwnedHqlExpr typedefExpr = $2.getExpr();
  4478. $$.setType(getTypedefType(typedefExpr));
  4479. $$.setPosition($1);
  4480. }
  4481. ;
  4482. userTypedefDictionary
  4483. : DICTIONARY_TYPE_ID {
  4484. OwnedHqlExpr typedefExpr = $1.getExpr();
  4485. $$.setType(getTypedefType(typedefExpr));
  4486. $$.setPosition($1);
  4487. }
  4488. | moduleScopeDot DICTIONARY_TYPE_ID leaveScope
  4489. {
  4490. $1.release();
  4491. OwnedHqlExpr typedefExpr = $2.getExpr();
  4492. $$.setType(getTypedefType(typedefExpr));
  4493. $$.setPosition($1);
  4494. }
  4495. ;
  4496. childDatasetOptions
  4497. :
  4498. { $$.setNullExpr(); }
  4499. | childDatasetOptions ',' childDatasetOption
  4500. {
  4501. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  4502. }
  4503. ;
  4504. childDatasetOption
  4505. : COUNT '(' expression ')'
  4506. {
  4507. parser->normalizeExpression($3);
  4508. $$.setExpr(createLinkAttribute(countAtom, $3.getExpr()));
  4509. $$.setPosition($1);
  4510. }
  4511. | SIZEOF '(' expression ')'
  4512. {
  4513. parser->normalizeExpression($3);
  4514. $$.setExpr(createLinkAttribute(sizeofAtom, $3.getExpr()));
  4515. $$.setPosition($1);
  4516. }
  4517. | LENGTH '(' expression ')'
  4518. {
  4519. parser->normalizeExpression($3);
  4520. $$.setExpr(createLinkAttribute(sizeofAtom, $3.getExpr()));
  4521. $$.setPosition($1);
  4522. }
  4523. | CHOOSEN '(' expression ')'
  4524. {
  4525. //theoretically possible to cope with variables, but serialization of self cause problems in code generator
  4526. parser->normalizeExpression($3, type_any, true);
  4527. $$.setExpr(createLinkAttribute(choosenAtom, $3.getExpr()));
  4528. $$.setPosition($1);
  4529. }
  4530. ;
  4531. typeDef
  4532. : scalarType
  4533. | recordDef {
  4534. OwnedHqlExpr e1 = $1.getExpr();
  4535. $$.setType(createRecordType(e1));
  4536. $$.setPosition($1);
  4537. }
  4538. ;
  4539. scalarType
  4540. : simpleType
  4541. | userTypedefType
  4542. | enumTypeId
  4543. {
  4544. OwnedHqlExpr expr = $1.getExpr();
  4545. $$.setType(expr->getType());
  4546. }
  4547. ;
  4548. query
  4549. : expression optfailure
  4550. {
  4551. parser->normalizeExpression($1);
  4552. IHqlExpression * expr = $1.getExpr();
  4553. IHqlExpression * failure = $2.getExpr();
  4554. if (failure)
  4555. {
  4556. if (expr->isDataset())
  4557. $$.setExpr(createDataset(no_colon, expr, failure));
  4558. else
  4559. {
  4560. //If a string value is stored, its type is a string of unknown length
  4561. //(because a different length string might be stored...)
  4562. Linked<ITypeInfo> type = expr->queryType();
  4563. #ifdef STORED_CAN_CHANGE_LENGTH
  4564. switch (type->getTypeCode())
  4565. {
  4566. case type_varstring:
  4567. case type_qstring:
  4568. case type_string:
  4569. case type_data:
  4570. case type_unicode:
  4571. case type_varunicode:
  4572. case type_utf8:
  4573. type.setown(getStretchedType(UNKNOWN_LENGTH, type));
  4574. break;
  4575. }
  4576. #endif
  4577. $$.setExpr(createValueF(no_colon, type.getClear(), expr, failure, NULL));
  4578. }
  4579. }
  4580. else
  4581. $$.setExpr(expr);
  4582. }
  4583. | dataSet optfailure
  4584. {
  4585. IHqlExpression * expr = $1.getExpr();
  4586. OwnedHqlExpr failure = $2.getExpr();
  4587. HqlExprArray meta;
  4588. expr = attachWorkflowOwn(meta, expr, failure, NULL);
  4589. expr = parser->attachPendingWarnings(expr);
  4590. expr = parser->attachMetaAttributes(expr, meta);
  4591. IHqlExpression *record = createValue(no_null);
  4592. OwnedHqlExpr select = createDatasetF(no_selectfields, expr, record, NULL);
  4593. HqlExprArray args;
  4594. args.append(*select.getClear());
  4595. IHqlExpression * output = createValue(no_output, makeVoidType(), args);
  4596. $$.setExpr(output, $1);
  4597. }
  4598. | dictionary optfailure
  4599. {
  4600. IHqlExpression * expr = $1.getExpr();
  4601. OwnedHqlExpr failure = $2.getExpr();
  4602. HqlExprArray meta;
  4603. expr = attachWorkflowOwn(meta, expr, failure, NULL);
  4604. expr = parser->attachPendingWarnings(expr);
  4605. expr = parser->attachMetaAttributes(expr, meta);
  4606. IHqlExpression * output = createValue(no_output, makeVoidType(), createDataset(no_datasetfromdictionary, expr));
  4607. $$.setExpr(output, $1);
  4608. }
  4609. | dataRow optfailure
  4610. {
  4611. IHqlExpression * expr = $1.getExpr();
  4612. OwnedHqlExpr failure = $2.getExpr();
  4613. HqlExprArray meta;
  4614. expr = attachWorkflowOwn(meta, expr, failure, NULL);
  4615. expr = parser->attachPendingWarnings(expr);
  4616. expr = parser->attachMetaAttributes(expr, meta);
  4617. $$.setExpr(createValue(no_outputscalar, makeVoidType(), expr), $1);
  4618. }
  4619. | action optfailure {
  4620. IHqlExpression * expr = $1.getExpr();
  4621. OwnedHqlExpr failure = $2.getExpr();
  4622. HqlExprArray meta;
  4623. expr = attachWorkflowOwn(meta, expr, failure, NULL);
  4624. expr = parser->attachPendingWarnings(expr);
  4625. expr = parser->attachMetaAttributes(expr, meta);
  4626. $$.setExpr(expr);
  4627. }
  4628. | BUILD '(' scopeFunction ')'
  4629. {
  4630. OwnedHqlExpr expr = $3.getExpr();
  4631. assertex(expr->getOperator() == no_funcdef);
  4632. IHqlExpression * moduleExpr = expr->queryChild(0);
  4633. parser->checkExportedModule($3, moduleExpr);
  4634. IHqlScope * concrete = moduleExpr->queryScope()->queryConcreteScope();
  4635. if (!concrete)
  4636. parser->reportError(ERR_ABSTRACT_MODULE, $3, "Library modules cannot be abstract");
  4637. $$.setExpr(expr.getClear());
  4638. $$.setPosition($1);
  4639. }
  4640. ;
  4641. optCommaExpression
  4642. : { $$.setNullExpr(); }
  4643. | ',' expression { $$.inherit($2); }
  4644. ;
  4645. optExpression
  4646. : { $$.setNullExpr(); }
  4647. | expression
  4648. ;
  4649. optConstBoolArg
  4650. : { $$.setNullExpr(); }
  4651. | '(' expression ')'
  4652. {
  4653. parser->normalizeExpression($2, type_boolean, true);
  4654. $$.inherit($2);
  4655. }
  4656. ;
  4657. booleanExpr
  4658. : expression {
  4659. parser->normalizeExpression($1, type_boolean, false);
  4660. $$.inherit($1);
  4661. }
  4662. ;
  4663. constExpression
  4664. : expression {
  4665. parser->normalizeExpression($1, type_any, true);
  4666. $$.inherit($1);
  4667. }
  4668. ;
  4669. expression
  4670. : scalarExpression
  4671. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN expression ';' endInlineFunctionToken
  4672. {
  4673. Owned<ITypeInfo> retType = $1.getType();
  4674. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  4675. }
  4676. ;
  4677. startCompoundExpression
  4678. : '@'
  4679. {
  4680. //Currently this is only used inside functionmacro to define an inline function.
  4681. parser->enterScope(false);
  4682. parser->enterCompoundObject();
  4683. parser->beginDefineId(NULL, NULL);
  4684. $$.setType(NULL);
  4685. }
  4686. ;
  4687. beginInlineFunctionToken
  4688. : FUNCTION // Will always work
  4689. | '{' // No so sure about this syntax - more concise, but not sure if in keeping with the rest of the language
  4690. ;
  4691. endInlineFunctionToken
  4692. : END
  4693. | '}' // see above
  4694. ;
  4695. condList
  4696. : booleanExpr {
  4697. parser->normalizeExpression($1, type_boolean, false);
  4698. $$.inherit($1);
  4699. }
  4700. | condList ',' booleanExpr
  4701. {
  4702. parser->normalizeExpression($3, type_boolean, false);
  4703. $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1);
  4704. }
  4705. ;
  4706. chooseList
  4707. : chooseItem
  4708. | chooseList ',' chooseItem
  4709. {
  4710. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  4711. $$.setPosition($1);
  4712. }
  4713. ;
  4714. chooseItem
  4715. : expression {
  4716. parser->normalizeExpression($1);
  4717. parser->applyDefaultPromotions($1, true);
  4718. $$.inherit($1);
  4719. }
  4720. ;
  4721. scalarExpression
  4722. : compareExpr
  4723. | NOT scalarExpression
  4724. {
  4725. ITypeInfo * type = $2.queryExprType();
  4726. if (type->getTypeCode() == type_boolean)
  4727. {
  4728. $$.setExpr(createBoolExpr(no_not, $2.getExpr()), $1);
  4729. }
  4730. else
  4731. {
  4732. parser->normalizeExpression($2, type_int, false);
  4733. IHqlExpression *e2 = $2.getExpr();
  4734. $$.setExpr(createValue(no_bnot, e2->getType(), e2), $1);
  4735. }
  4736. }
  4737. | scalarExpression AND scalarExpression
  4738. {
  4739. parser->normalizeExpression($1, type_boolean, false);
  4740. parser->normalizeExpression($3, type_boolean, false);
  4741. $$.setExpr(createBoolExpr(no_and, $1.getExpr(), $3.getExpr()));
  4742. $$.setPosition($1);
  4743. }
  4744. | scalarExpression OR scalarExpression
  4745. {
  4746. parser->normalizeExpression($1, type_boolean, false);
  4747. parser->normalizeExpression($3, type_boolean, false);
  4748. $$.setExpr(createBoolExpr(no_or, $1.getExpr(), $3.getExpr()));
  4749. $$.setPosition($1);
  4750. }
  4751. /*
  4752. | scalarExpression XOR scalarExpression
  4753. {
  4754. parser->normalizeExpression($1, type_boolean, false);
  4755. parser->normalizeExpression($3, type_boolean, false);
  4756. $$.setExpr(createBoolExpr(no_ne, $1.getExpr(), $3.getExpr()));
  4757. $$.setPosition($1);
  4758. }
  4759. */
  4760. | WITHIN dataSet {
  4761. OwnedHqlExpr ds = $2.getExpr();
  4762. $$.setExpr(createBoolExpr(no_within, ds.getClear()));
  4763. $$.setPosition($1);
  4764. }
  4765. ;
  4766. heterogeneous_expr_list
  4767. : heterogeneous_expr_list_open
  4768. { $$.setExpr($1.getExpr()->closeExpr()); }
  4769. ;
  4770. heterogeneous_expr_list_open
  4771. : expression {
  4772. parser->normalizeExpression($1);
  4773. IHqlExpression *elem = $1.getExpr();
  4774. IHqlExpression *list = createOpenValue(no_comma, elem->getType());
  4775. list->addOperand(elem);
  4776. $$.setExpr(list);
  4777. }
  4778. | heterogeneous_expr_list_open ',' expression
  4779. {
  4780. parser->normalizeExpression($3);
  4781. IHqlExpression *list = $1.getExpr();
  4782. list->addOperand($3.getExpr());
  4783. $$.setExpr(list);
  4784. }
  4785. ;
  4786. compareExpr
  4787. : expr compareOp expr
  4788. {
  4789. parser->normalizeExpression($1);
  4790. parser->normalizeExpression($3);
  4791. node_operator op = (node_operator)$2.getInt();
  4792. parser->promoteToSameCompareType($1, $3, op);
  4793. $$.setExpr(createBoolExpr(op, $1.getExpr(), $3.getExpr()), $1);
  4794. }
  4795. | expr BETWEEN expr AND expr
  4796. {
  4797. parser->normalizeExpression($1);
  4798. parser->normalizeExpression($3);
  4799. parser->normalizeExpression($5);
  4800. parser->promoteToSameCompareType($1, $3, $5);
  4801. $$.setExpr(createBoolExpr(no_between, $1.getExpr(), $3.getExpr(), $5.getExpr()));
  4802. }
  4803. | expr NOT BETWEEN expr AND expr
  4804. {
  4805. parser->normalizeExpression($1);
  4806. parser->normalizeExpression($4);
  4807. parser->normalizeExpression($6);
  4808. parser->promoteToSameCompareType($1, $4, $6);
  4809. $$.setExpr(createValue(no_not, makeBoolType(), createBoolExpr(no_between, $1.getExpr(), $4.getExpr(), $6.getExpr())));
  4810. }
  4811. | expr NOT TOK_IN expr
  4812. {
  4813. parser->normalizeExpression($1);
  4814. parser->normalizeExpression($4);
  4815. parser->normalizeExpression($4, type_set, false);
  4816. IHqlExpression *set = $4.getExpr();
  4817. IHqlExpression *expr = $1.getExpr();
  4818. $$.setExpr(parser->createINExpression(no_notin, expr, set, $4));
  4819. $$.setPosition($3);
  4820. }
  4821. | expr TOK_IN expr
  4822. {
  4823. parser->normalizeExpression($1);
  4824. parser->normalizeExpression($3);
  4825. parser->normalizeExpression($3, type_set, false);
  4826. IHqlExpression *set = $3.getExpr();
  4827. IHqlExpression *expr = $1.getExpr();
  4828. $$.setExpr(parser->createINExpression(no_in, expr, set, $3));
  4829. $$.setPosition($2);
  4830. }
  4831. | expr NOT TOK_IN dictionary
  4832. {
  4833. parser->normalizeExpression($1);
  4834. parser->normalizeExpression($4);
  4835. parser->normalizeExpression($4, type_dictionary, false);
  4836. OwnedHqlExpr dict = $4.getExpr();
  4837. OwnedHqlExpr row = createValue(no_rowvalue, makeNullType(), $1.getExpr());
  4838. OwnedHqlExpr indict = createINDictExpr(*parser->errorHandler, $4.pos, row, dict);
  4839. $$.setExpr(getInverse(indict));
  4840. $$.setPosition($3);
  4841. }
  4842. | dataRow NOT TOK_IN dictionary
  4843. {
  4844. parser->normalizeExpression($1);
  4845. parser->normalizeExpression($4);
  4846. parser->normalizeExpression($4, type_dictionary, false);
  4847. OwnedHqlExpr dict = $4.getExpr();
  4848. OwnedHqlExpr row = $1.getExpr();
  4849. OwnedHqlExpr indict = createINDictRow(*parser->errorHandler, $4.pos, row, dict);
  4850. $$.setExpr(getInverse(indict));
  4851. $$.setPosition($3);
  4852. }
  4853. | expr TOK_IN dictionary
  4854. {
  4855. parser->normalizeExpression($1);
  4856. parser->normalizeExpression($3);
  4857. parser->normalizeExpression($3, type_dictionary, false);
  4858. OwnedHqlExpr dict = $3.getExpr();
  4859. OwnedHqlExpr row = createValue(no_rowvalue, makeNullType(), $1.getExpr());
  4860. $$.setExpr(createINDictExpr(*parser->errorHandler, $3.pos, row, dict));
  4861. $$.setPosition($2);
  4862. }
  4863. | dataRow TOK_IN dictionary
  4864. {
  4865. parser->normalizeExpression($1);
  4866. parser->normalizeExpression($3);
  4867. parser->normalizeExpression($3, type_dictionary, false);
  4868. OwnedHqlExpr dict = $3.getExpr();
  4869. OwnedHqlExpr row = $1.getExpr();
  4870. $$.setExpr(createINDictRow(*parser->errorHandler, $3.pos, row, dict));
  4871. $$.setPosition($2);
  4872. }
  4873. | dataSet EQ dataSet
  4874. {
  4875. parser->checkSameType($1, $3); $$.setExpr(createBoolExpr(no_eq, $1.getExpr(), $3.getExpr()));
  4876. }
  4877. | dataSet NE dataSet
  4878. {
  4879. parser->checkSameType($1, $3); $$.setExpr(createBoolExpr(no_ne, $1.getExpr(), $3.getExpr()));
  4880. }
  4881. | dataRow EQ dataRow
  4882. {
  4883. parser->checkSameType($1, $3); $$.setExpr(createBoolExpr(no_eq, $1.getExpr(), $3.getExpr()));
  4884. }
  4885. | dataRow NE dataRow
  4886. {
  4887. parser->checkSameType($1, $3); $$.setExpr(createBoolExpr(no_ne, $1.getExpr(), $3.getExpr()));
  4888. }
  4889. | expr
  4890. ;
  4891. compareOp
  4892. : EQ { $$.setInt(no_eq); }
  4893. | NE { $$.setInt(no_ne); }
  4894. | LE { $$.setInt(no_le); }
  4895. | GE { $$.setInt(no_ge); }
  4896. | LT { $$.setInt(no_lt); }
  4897. | GT { $$.setInt(no_gt); }
  4898. ;
  4899. expr
  4900. : primexpr
  4901. | expr '+' expr {
  4902. parser->normalizeExpression($1);
  4903. parser->normalizeExpression($3);
  4904. if ($1.queryExpr()->isList() || $3.queryExpr()->isList())
  4905. {
  4906. ITypeInfo * type = parser->promoteToSameType($1, $3);
  4907. $$.setExpr(createValue(no_addsets, type, $1.getExpr(), $3.getExpr()), $1);
  4908. }
  4909. else if (isUnicodeType($1.queryExprType()) || isUnicodeType($3.queryExprType()))
  4910. {
  4911. parser->normalizeExpression($1, type_unicode, false);
  4912. parser->normalizeExpression($3, type_unicode, false);
  4913. IAtom * locale = parser->ensureCommonLocale($1, $3);
  4914. // cannot be certain of length of concatenated unicode string due to normalization
  4915. ITypeInfo * type;
  4916. if(($1.queryExprType()->getTypeCode() == type_utf8) && ($3.queryExprType()->getTypeCode() == type_utf8))
  4917. type = makeUtf8Type(UNKNOWN_LENGTH, locale);
  4918. else
  4919. type = makeUnicodeType(UNKNOWN_LENGTH, locale);
  4920. OwnedHqlExpr left = $1.getExpr();
  4921. OwnedHqlExpr right = $3.getExpr();
  4922. $$.setExpr(createValue(no_concat, type, ensureExprType(left, type), ensureExprType(right, type)), $1);
  4923. }
  4924. else if (isStringType($1.queryExprType()) || isStringType($3.queryExprType()))
  4925. {
  4926. parser->ensureString($1);
  4927. parser->ensureString($3);
  4928. ITypeInfo * t1 = $1.queryExprType();
  4929. ITypeInfo * t2 = $3.queryExprType();
  4930. unsigned l = t1->getStringLen();
  4931. unsigned r = t2->getStringLen();
  4932. unsigned size = UNKNOWN_LENGTH;
  4933. if ((l != UNKNOWN_LENGTH) && (r != UNKNOWN_LENGTH))
  4934. size = l + r;
  4935. //MORE: case sensitive?
  4936. ICharsetInfo * charset = t1->queryCharset();
  4937. ICharsetInfo * otherCharset = t2->queryCharset();
  4938. if (queryDefaultTranslation(charset, otherCharset))
  4939. parser->reportError(ERR_CHARSET_CONFLICT, $3, "Different character sets in concatenation");
  4940. ICollationInfo * collation = t1->queryCollation(); // MORE!!
  4941. ITypeInfo * type;
  4942. if ((t1->getTypeCode() == type_varstring) || (t2->getTypeCode() == type_varstring))
  4943. type = makeVarStringType(size);
  4944. else if ((t1->getTypeCode() == type_string) || (t2->getTypeCode() == type_string))
  4945. type = makeStringType(size, LINK(charset), LINK(collation));
  4946. else
  4947. type = makeDataType(size);
  4948. $$.setExpr(createValue(no_concat, type, $1.getExpr(), $3.getExpr()), $1);
  4949. }
  4950. else
  4951. {
  4952. $$.setExpr(parser->createArithmeticOp(no_add, $1, $3), $1);
  4953. }
  4954. }
  4955. | expr '-' expr
  4956. {
  4957. $$.setExpr(parser->createArithmeticOp(no_sub, $1, $3), $1);
  4958. }
  4959. | expr ORDER expr
  4960. {
  4961. parser->normalizeExpression($1);
  4962. parser->normalizeExpression($3);
  4963. ::Release(parser->checkPromoteType($1, $3));
  4964. $$.setExpr(createValue(no_order, makeIntType(4, true), $1.getExpr(), $3.getExpr()));
  4965. }
  4966. | expr '*' expr
  4967. {
  4968. $$.setExpr(parser->createArithmeticOp(no_mul, $1, $3), $1);
  4969. }
  4970. | expr '/' expr
  4971. {
  4972. parser->normalizeExpression($1);
  4973. parser->normalizeExpression($3);
  4974. if (!isDecimalType($1.queryExprType()) && !isDecimalType($3.queryExprType()))
  4975. parser->ensureType($1, parser->defaultRealType);
  4976. $$.setExpr(parser->createArithmeticOp(no_div, $1, $3), $1);
  4977. }
  4978. | expr '%' expr {
  4979. parser->normalizeExpression($1, type_int, false);
  4980. parser->normalizeExpression($3, type_int, false);
  4981. parser->applyDefaultPromotions($1, true);
  4982. parser->applyDefaultPromotions($3, false);
  4983. ITypeInfo * type = parser->promoteToSameType($1, $3); // MORE _ should calculate at wider width then cast down to narrower?
  4984. $$.setExpr(createValue(no_modulus, type, $1.getExpr(), $3.getExpr()));
  4985. }
  4986. | expr DIV expr {
  4987. parser->normalizeExpression($1);
  4988. parser->normalizeExpression($3);
  4989. parser->applyDefaultPromotions($1, true);
  4990. parser->applyDefaultPromotions($3, false);
  4991. parser->normalizeExpression($1, type_int, false);
  4992. parser->normalizeExpression($3, type_int, false);
  4993. ITypeInfo * type = parser->promoteToSameType($1, $3);
  4994. $$.setExpr(createValue(no_div, type, $1.getExpr(), $3.getExpr()));
  4995. }
  4996. | expr SHIFTL expr {
  4997. parser->normalizeExpression($1);
  4998. parser->normalizeExpression($3);
  4999. parser->applyDefaultPromotions($1, true);
  5000. parser->normalizeExpression($1, type_int, false);
  5001. parser->normalizeExpression($3, type_int, false);
  5002. IHqlExpression * left = $1.getExpr();
  5003. $$.setExpr(createValue(no_lshift, left->getType(), left, $3.getExpr()));
  5004. }
  5005. | expr SHIFTR expr {
  5006. parser->normalizeExpression($1);
  5007. parser->normalizeExpression($3);
  5008. parser->applyDefaultPromotions($1, false);
  5009. parser->normalizeExpression($1, type_int, false);
  5010. parser->normalizeExpression($3, type_int, false);
  5011. IHqlExpression * left = $1.getExpr();
  5012. $$.setExpr(createValue(no_rshift, left->getType(), left, $3.getExpr()));
  5013. }
  5014. | expr '&' expr {
  5015. parser->normalizeExpression($1);
  5016. parser->normalizeExpression($3);
  5017. //MORE: We could could implement for decimal types.
  5018. if (!$1.queryExpr()->isBoolean() || !$3.queryExpr()->isBoolean())
  5019. {
  5020. parser->normalizeExpression($1, type_int, false);
  5021. parser->normalizeExpression($3, type_int, false);
  5022. }
  5023. ITypeInfo * lType = $1.queryExprType()->queryPromotedType();
  5024. ITypeInfo * rType = $3.queryExprType()->queryPromotedType();
  5025. ITypeInfo * type = getBandType(lType, rType);
  5026. parser->ensureType($1, type);
  5027. parser->ensureType($3, type);
  5028. $$.setExpr(createValue(no_band, type, $1.getExpr(), $3.getExpr()));
  5029. }
  5030. | expr '|' expr {
  5031. parser->normalizeExpression($1);
  5032. parser->normalizeExpression($3);
  5033. if (!$1.queryExpr()->isBoolean() || !$3.queryExpr()->isBoolean())
  5034. {
  5035. parser->normalizeExpression($1, type_int, false);
  5036. parser->normalizeExpression($3, type_int, false);
  5037. }
  5038. ITypeInfo * lType = $1.queryExprType()->queryPromotedType();
  5039. ITypeInfo * rType = $3.queryExprType()->queryPromotedType();
  5040. ITypeInfo * type = getBorType(lType, rType);
  5041. parser->ensureType($1, type);
  5042. parser->ensureType($3, type);
  5043. $$.setExpr(createValue(no_bor, type, $1.getExpr(), $3.getExpr()));
  5044. }
  5045. | expr '^' expr {
  5046. parser->normalizeExpression($1);
  5047. parser->normalizeExpression($3);
  5048. parser->normalizeExpression($1, type_int, false);
  5049. parser->normalizeExpression($3, type_int, false);
  5050. ITypeInfo * type = parser->promoteToSameType($1, $3);
  5051. $$.setExpr(createValue(no_bxor, type, $1.getExpr(), $3.getExpr()));
  5052. }
  5053. /* | expr '[' rangeExpr ']'
  5054. {
  5055. parser->ensureTypeCanBeIndexed($1);
  5056. // MORE - result type is shorter if expressions are constant, same as input if not
  5057. ITypeInfo * subtype = parser->checkStringIndex($1, $3);
  5058. $$.setExpr(createValue(no_substring, subtype, $1.getExpr(), $3.getExpr()));
  5059. }
  5060. */
  5061. ;
  5062. rangeOrIndices
  5063. : rangeExpr
  5064. ;
  5065. rangeExpr
  5066. : expression {
  5067. parser->normalizeExpression($1, type_int, false);
  5068. parser->checkPositive($1);
  5069. $$.setExpr($1.getExpr());
  5070. }
  5071. | expression DOTDOT expression
  5072. {
  5073. parser->normalizeExpression($1, type_int, false);
  5074. parser->normalizeExpression($3, type_int, false);
  5075. parser->checkPositive($1);
  5076. parser->checkPositive($3);
  5077. $$.setExpr(createValue(no_range, makeNullType(), $1.getExpr(), $3.getExpr()));
  5078. }
  5079. | DOTDOT expression {
  5080. parser->normalizeExpression($2, type_int, false);
  5081. parser->checkPositive($2);
  5082. $$.setExpr(createValue(no_rangeto, makeNullType(), $2.getExpr()));
  5083. }
  5084. | expression DOTDOT {
  5085. parser->normalizeExpression($1, type_int, false);
  5086. parser->checkPositive($1);
  5087. $$.setExpr(createValue(no_rangefrom, makeNullType(), $1.getExpr()));
  5088. }
  5089. | expression DOTDOT '*'
  5090. {
  5091. parser->normalizeExpression($1, type_int, false);
  5092. parser->checkPositive($1);
  5093. $$.setExpr(createValue(no_rangecommon, makeNullType(), $1.getExpr()));
  5094. }
  5095. | {
  5096. parser->reportError(ERR_SUBSTR_EMPTYRANGE,yylval,"Empty range");
  5097. // recovering: assume [1..].
  5098. $$.setExpr(createValue(no_rangefrom, makeNullType(), createConstant(1)));
  5099. }
  5100. ;
  5101. primexpr
  5102. : primexpr1
  5103. | '-' primexpr {
  5104. parser->normalizeExpression($2);
  5105. if (parser->sortDepth == 0)
  5106. {
  5107. parser->applyDefaultPromotions($2, true);
  5108. parser->normalizeExpression($2, type_numeric, false);
  5109. }
  5110. IHqlExpression *e2 = $2.getExpr();
  5111. $$.setExpr(createValue(no_negate, e2->getType(), e2));
  5112. }
  5113. | '+' primexpr {
  5114. parser->normalizeExpression($2);
  5115. if (parser->sortDepth == 0)
  5116. parser->normalizeExpression($2, type_numeric, false);
  5117. $$.setExpr($2.getExpr());
  5118. }
  5119. | BNOT primexpr {
  5120. parser->normalizeExpression($2, type_int, false);
  5121. IHqlExpression *e2 = $2.getExpr();
  5122. $$.setExpr(createValue(no_bnot, e2->getType(), e2));
  5123. }
  5124. | '(' scalarType ')' primexpr
  5125. {
  5126. parser->normalizeExpression($4, type_scalar, false);
  5127. Owned<ITypeInfo> type = $2.getType();
  5128. OwnedHqlExpr expr = $4.getExpr();
  5129. $$.setExpr(getCastExpr(expr, type));
  5130. }
  5131. | '(' setType ')' primexpr
  5132. {
  5133. parser->normalizeExpression($4, type_set, false);
  5134. Owned<ITypeInfo> type = $2.getType();
  5135. OwnedHqlExpr expr = $4.getExpr();
  5136. $$.setExpr(createValue(no_cast, type.getClear(), expr.getClear()), $1);
  5137. }
  5138. | transfer primexpr {
  5139. parser->normalizeExpression($2);
  5140. IHqlExpression *expr = $2.getExpr();
  5141. ITypeInfo *exprType = expr->queryType();
  5142. ITypeInfo *type = $1.getType();
  5143. if ((exprType->getSize() != UNKNOWN_LENGTH) && (exprType->getSize() < type->getSize()) && type->getSize() != UNKNOWN_LENGTH)
  5144. parser->reportError(ERR_TYPETRANS_LARGERTYPE, $1, "Type transfer: target type in is larger than source type");
  5145. $$.setExpr(createValue(no_typetransfer, type, expr));
  5146. }
  5147. ;
  5148. primexpr1
  5149. : atomicValue
  5150. | primexpr1 '[' rangeOrIndices ']'
  5151. {
  5152. parser->normalizeExpression($1);
  5153. if ($1.queryExpr()->isList())
  5154. {
  5155. $$.setExpr(parser->createListIndex($1, $3, NULL), $1);
  5156. }
  5157. else
  5158. {
  5159. parser->ensureTypeCanBeIndexed($1);
  5160. // MORE - result type is shorter if expressions are constant, same as input if not
  5161. ITypeInfo * subtype = parser->checkStringIndex($1, $3);
  5162. $$.setExpr(createValue(no_substring, subtype, $1.getExpr(), $3.getExpr()), $1);
  5163. }
  5164. }
  5165. | primexpr1 '[' NOBOUNDCHECK rangeOrIndices ']'
  5166. {
  5167. parser->normalizeExpression($1, type_set, false);
  5168. $$.setExpr(parser->createListIndex($1, $4, createAttribute(noBoundCheckAtom)));
  5169. $$.setPosition($1);
  5170. }
  5171. | '(' expression ')'
  5172. { $$.inherit($2); }
  5173. | COUNT '(' startTopFilter aggregateFlags ')' endTopFilter
  5174. {
  5175. $$.setExpr(createValue(no_count, LINK(parser->defaultIntegralType), $3.getExpr(), $4.getExpr()));
  5176. }
  5177. | COUNT '(' GROUP optExtraFilter ')'
  5178. {
  5179. $$.setExpr(createValue(no_countgroup, LINK(parser->defaultIntegralType), $4.getExpr()));
  5180. }
  5181. | COUNT '(' SORTLIST_ID ')'
  5182. {
  5183. OwnedHqlExpr list = $3.getExpr();
  5184. //list could either be a no_sortlist - in which case we want the number of elements,
  5185. //or a no_param, in which case it doesn't matter what we return
  5186. $$.setExpr(getSizetConstant(list->numChildren()), $1);
  5187. }
  5188. | COUNT '(' dictionary ')'
  5189. {
  5190. $$.setExpr(createValue(no_countdict, LINK(parser->defaultIntegralType), $3.getExpr()));
  5191. }
  5192. | CHOOSE '(' expression ',' chooseList ')'
  5193. {
  5194. parser->normalizeExpression($3, type_int, false);
  5195. HqlExprArray args;
  5196. $5.unwindCommaList(args);
  5197. ITypeInfo * retType = parser->promoteToSameType(args, $5, NULL, false); // should be true
  5198. args.add(*$3.getExpr(),0);
  5199. $$.setExpr(createValue(no_choose, retType, args));
  5200. }
  5201. | EXISTS '(' GROUP optExtraFilter ')'
  5202. {
  5203. $$.setExpr(createValue(no_existsgroup, makeBoolType(), $4.getExpr()));
  5204. }
  5205. | EXISTS '(' dataSet aggregateFlags ')'
  5206. {
  5207. $$.setExpr(createBoolExpr(no_exists, $3.getExpr(), $4.getExpr()));
  5208. $$.setPosition($1);
  5209. }
  5210. | EXISTS '(' dictionary ')'
  5211. {
  5212. $$.setExpr(createValue(no_existsdict, makeBoolType(), $3.getExpr()));
  5213. }
  5214. | MAP '(' mapSpec ',' expression ')'
  5215. {
  5216. parser->normalizeExpression($5);
  5217. HqlExprArray args;
  5218. $3.unwindCommaList(args);
  5219. ITypeInfo * retType = parser->promoteMapToSameType(args, $5);
  5220. args.append(*$5.getExpr());
  5221. $$.setExpr(createValue(no_map, retType, args));
  5222. }
  5223. | CASE '(' expression ',' beginList caseSpec ',' expression ')'
  5224. {
  5225. parser->normalizeExpression($3);
  5226. parser->normalizeExpression($8);
  5227. HqlExprArray args;
  5228. parser->endList(args);
  5229. parser->checkCaseForDuplicates(args, $6);
  5230. ITypeInfo * retType = parser->promoteCaseToSameType($3, args, $8);
  5231. args.add(*$3.getExpr(),0);
  5232. args.append(*$8.getExpr());
  5233. $$.setExpr(createValue(no_case, retType, args));
  5234. }
  5235. | CASE '(' expression ',' beginList expression ')'
  5236. {
  5237. parser->normalizeExpression($3);
  5238. parser->normalizeExpression($6);
  5239. // change error to warning.
  5240. parser->reportWarning(WRN_CASENOCONDITION, $1.pos, "CASE does not have any conditions");
  5241. HqlExprArray args;
  5242. parser->endList(args);
  5243. ::Release($3.getExpr());
  5244. $$.setExpr($6.getExpr(), $1);
  5245. }
  5246. | IF '(' booleanExpr ',' expression ',' expression ')'
  5247. {
  5248. parser->normalizeExpression($5);
  5249. parser->normalizeExpression($7);
  5250. ITypeInfo * type = parser->checkPromoteIfType($5, $7);
  5251. $$.setExpr(createValue(no_if, type, $3.getExpr(), $5.getExpr(), $7.getExpr()), $1);
  5252. }
  5253. | IFF '(' booleanExpr ',' expression ',' expression ')'
  5254. {
  5255. parser->normalizeExpression($5);
  5256. parser->normalizeExpression($7);
  5257. $$.setExpr(parser->createIff($3, $5, $7), $1);
  5258. }
  5259. | EXP '(' expression ')'
  5260. {
  5261. parser->normalizeExpression($3, type_real, false);
  5262. $$.setExpr(createValue(no_exp, makeRealType(8), $3.getExpr()));
  5263. }
  5264. | HASH '(' beginList sortList ')'
  5265. {
  5266. HqlExprArray sortItems;
  5267. parser->endList(sortItems);
  5268. IHqlExpression * hash = parser->processSortList($4, no_hash, NULL, sortItems, NULL, NULL);
  5269. $$.setExpr(createValue(no_hash, LINK(parser->uint4Type), hash));
  5270. }
  5271. | HASH32 '(' beginList sortList ')'
  5272. {
  5273. HqlExprArray sortItems;
  5274. parser->endList(sortItems);
  5275. IHqlExpression * hash = parser->processSortList($4, no_hash, NULL, sortItems, NULL, NULL);
  5276. $$.setExpr(createValue(no_hash32, makeIntType(4, false), hash));
  5277. }
  5278. | HASH64 '(' beginList sortList ')'
  5279. {
  5280. HqlExprArray sortItems;
  5281. parser->endList(sortItems);
  5282. IHqlExpression * hash = parser->processSortList($4, no_hash, NULL, sortItems, NULL, NULL);
  5283. $$.setExpr(createValue(no_hash64, makeIntType(8, false), hash));
  5284. }
  5285. | HASHMD5 '(' beginList sortList ')'
  5286. {
  5287. HqlExprArray sortItems;
  5288. parser->endList(sortItems);
  5289. IHqlExpression * hash = parser->processSortList($4, no_hash, NULL, sortItems, NULL, NULL);
  5290. $$.setExpr(createValue(no_hashmd5, makeDataType(16), hash));
  5291. }
  5292. | CRC '(' beginList sortList ')'
  5293. {
  5294. HqlExprArray sortItems;
  5295. parser->endList(sortItems);
  5296. IHqlExpression * hash = parser->processSortList($4, no_hash, NULL, sortItems, NULL, NULL);
  5297. $$.setExpr(createValue(no_crc, LINK(parser->uint4Type), hash), $1);
  5298. }
  5299. | ECLCRC '(' goodObject ')'
  5300. {
  5301. $$.setExpr(createValue(no_eclcrc, LINK(parser->uint4Type), createAttribute(_original_Atom, $3.getExpr())), $1);
  5302. }
  5303. | ECLCRC '(' goodObject ',' PARSE ')'
  5304. {
  5305. OwnedHqlExpr expr = $3.getExpr();
  5306. $$.setExpr(getSizetConstant(getExpressionCRC(expr)));
  5307. }
  5308. | LN '(' expression ')'
  5309. {
  5310. parser->normalizeExpression($3, type_real, false);
  5311. $$.setExpr(createValue(no_ln, makeRealType(8), $3.getExpr()));
  5312. }
  5313. | SIN '(' expression ')'
  5314. {
  5315. parser->normalizeExpression($3, type_real, false);
  5316. $$.setExpr(createValue(no_sin, makeRealType(8), $3.getExpr()));
  5317. }
  5318. | COS '(' expression ')'
  5319. {
  5320. parser->normalizeExpression($3, type_real, false);
  5321. $$.setExpr(createValue(no_cos, makeRealType(8), $3.getExpr()));
  5322. }
  5323. | TAN '(' expression ')'
  5324. {
  5325. parser->normalizeExpression($3, type_real, false);
  5326. $$.setExpr(createValue(no_tan, makeRealType(8), $3.getExpr()));
  5327. }
  5328. | ASIN '(' expression ')'
  5329. {
  5330. parser->normalizeExpression($3, type_real, false);
  5331. $$.setExpr(createValue(no_asin, makeRealType(8), $3.getExpr()));
  5332. }
  5333. | ACOS '(' expression ')'
  5334. {
  5335. parser->normalizeExpression($3, type_real, false);
  5336. $$.setExpr(createValue(no_acos, makeRealType(8), $3.getExpr()));
  5337. }
  5338. | ATAN '(' expression ')'
  5339. {
  5340. parser->normalizeExpression($3, type_real, false);
  5341. $$.setExpr(createValue(no_atan, makeRealType(8), $3.getExpr()));
  5342. }
  5343. | ATAN2 '(' expression ',' expression ')'
  5344. {
  5345. parser->normalizeExpression($3, type_real, false);
  5346. parser->normalizeExpression($5, type_real, false);
  5347. $$.setExpr(createValue(no_atan2, makeRealType(8), $3.getExpr(), $5.getExpr()));
  5348. }
  5349. | SINH '(' expression ')'
  5350. {
  5351. parser->normalizeExpression($3, type_real, false);
  5352. $$.setExpr(createValue(no_sinh, makeRealType(8), $3.getExpr()));
  5353. }
  5354. | COSH '(' expression ')'
  5355. {
  5356. parser->normalizeExpression($3, type_real, false);
  5357. $$.setExpr(createValue(no_cosh, makeRealType(8), $3.getExpr()));
  5358. }
  5359. | TANH '(' expression ')'
  5360. {
  5361. parser->normalizeExpression($3, type_real, false);
  5362. $$.setExpr(createValue(no_tanh, makeRealType(8), $3.getExpr()));
  5363. }
  5364. | GLOBAL '(' expression globalOpts ')'
  5365. {
  5366. parser->normalizeExpression($3);
  5367. IHqlExpression * value = $3.getExpr();
  5368. $$.setExpr(createValueF(no_globalscope, value->getType(), value, $4.getExpr(), NULL));
  5369. $$.setPosition($1);
  5370. }
  5371. | TOK_LOG '(' expression ')'
  5372. {
  5373. parser->normalizeExpression($3, type_real, false);
  5374. $$.setExpr(createValue(no_log10, makeRealType(8), $3.getExpr()));
  5375. }
  5376. | POWER '(' expression ',' expression ')'
  5377. {
  5378. parser->normalizeExpression($3, type_real, false);
  5379. parser->normalizeExpression($5, type_numeric, false);
  5380. $$.setExpr(createValue(no_power, makeRealType(8),$3.getExpr(), $5.getExpr()));
  5381. }
  5382. | RANDOM '(' ')'
  5383. {
  5384. $$.setExpr(createValue(no_random, LINK(parser->uint4Type), parser->createUniqueId()));
  5385. }
  5386. | ROUND '(' expression ')'
  5387. {
  5388. parser->normalizeExpression($3, type_numeric, false);
  5389. ITypeInfo * type = getRoundType($3.queryExprType());
  5390. $$.setExpr(createValue(no_round, type, $3.getExpr()));
  5391. }
  5392. | ROUND '(' expression ',' expression ')'
  5393. {
  5394. parser->normalizeExpression($3, type_numeric, false);
  5395. ITypeInfo * type = getRoundToType($3.queryExprType());
  5396. $$.setExpr(createValue(no_round, type, $3.getExpr(), $5.getExpr()));
  5397. }
  5398. | ROUNDUP '(' expression ')'
  5399. {
  5400. parser->normalizeExpression($3, type_numeric, false);
  5401. ITypeInfo * type = getRoundType($3.queryExprType());
  5402. $$.setExpr(createValue(no_roundup, type, $3.getExpr()));
  5403. }
  5404. | SQRT '(' expression ')'
  5405. {
  5406. parser->normalizeExpression($3, type_real, false);
  5407. $$.setExpr(createValue(no_sqrt, makeRealType(8), $3.getExpr()));
  5408. }
  5409. | TRUNCATE '(' expression ')'
  5410. {
  5411. parser->normalizeExpression($3, type_numeric, false);
  5412. ITypeInfo * type = getTruncType($3.queryExprType());
  5413. $$.setExpr(createValue(no_truncate, type, $3.getExpr()));
  5414. }
  5415. | LENGTH '(' expression ')'
  5416. {
  5417. parser->normalizeExpression($3, type_stringorunicode, false);
  5418. $$.setExpr(createValue(no_charlen, LINK(parser->uint4Type), $3.getExpr()));
  5419. }
  5420. | TRIM '(' expression optTrimFlags ')'
  5421. {
  5422. parser->normalizeExpression($3, type_stringorunicode, false);
  5423. OwnedHqlExpr expr = $3.getExpr();
  5424. OwnedHqlExpr flags = $4.getExpr();
  5425. $$.setExpr(createTrimExpr(expr, flags));
  5426. }
  5427. | NOFOLD '(' expression ')'
  5428. {
  5429. parser->normalizeExpression($3);
  5430. IHqlExpression * expr = $3.getExpr();
  5431. $$.setExpr(createValue(no_nofold, expr->getType(), expr));
  5432. }
  5433. | NOHOIST '(' expression ')'
  5434. {
  5435. parser->normalizeExpression($3);
  5436. IHqlExpression * expr = $3.getExpr();
  5437. $$.setExpr(createValue(no_nohoist, expr->getType(), expr));
  5438. }
  5439. | NOTHOR '(' expression ')'
  5440. {
  5441. parser->normalizeExpression($3);
  5442. IHqlExpression * expr = $3.getExpr();
  5443. $$.setExpr(createValue(no_nothor, expr->getType(), expr));
  5444. }
  5445. | ABS '(' expression ')'
  5446. {
  5447. parser->normalizeExpression($3, type_numeric, false);
  5448. IHqlExpression * expr = $3.getExpr();
  5449. $$.setExpr(createValue(no_abs, expr->getType(), expr), $1);
  5450. }
  5451. | INTFORMAT '(' expression ',' expression ',' expression ')'
  5452. {
  5453. parser->normalizeExpression($3, type_int, false);
  5454. parser->normalizeExpression($5, type_int, false);
  5455. parser->normalizeExpression($7, type_int, false);
  5456. IHqlExpression *len = $5.getExpr();
  5457. IHqlExpression *flen = foldHqlExpression(len);
  5458. IValue *length = flen->queryValue();
  5459. unsigned resultSize = UNKNOWN_LENGTH;
  5460. if (length)
  5461. {
  5462. resultSize = (unsigned) length->getIntValue();
  5463. if ((int) resultSize < 0)
  5464. {
  5465. resultSize = 0;
  5466. parser->reportError(ERR_NEGATIVE_WIDTH, $5, "INTFORMAT does not support negative widths");
  5467. }
  5468. }
  5469. $$.setExpr(createValue(no_intformat, makeStringType(resultSize, NULL, NULL), $3.getExpr(), flen, $7.getExpr()));
  5470. len->Release();
  5471. }
  5472. | REALFORMAT '(' expression ',' expression ',' expression ')'
  5473. {
  5474. parser->normalizeExpression($3, type_real, false);
  5475. parser->normalizeExpression($5, type_int, false);
  5476. parser->normalizeExpression($7, type_int, false);
  5477. OwnedHqlExpr flen = foldHqlExpression($5.queryExpr());
  5478. IValue *length = flen->queryValue();
  5479. if (length && (length->getIntValue() < 0))
  5480. parser->reportError(ERR_NEGATIVE_WIDTH, $5, "REALFORMAT does not support negative widths");
  5481. $$.setExpr(createValue(no_realformat, makeStringType(UNKNOWN_LENGTH, NULL, NULL), $3.getExpr(), $5.getExpr(), $7.getExpr()));
  5482. }
  5483. | TOXML '(' dataRow ')'
  5484. {
  5485. //MORE Could allow ,NOTRIM,OPT,???flags
  5486. $$.setExpr(createValue(no_toxml, makeUtf8Type(UNKNOWN_LENGTH, NULL), $3.getExpr()));
  5487. }
  5488. | REGEXFIND '(' expression ',' expression regexOpt ')'
  5489. {
  5490. parser->normalizeExpression($3, type_stringorunicode, false);
  5491. if(isUnicodeType($3.queryExprType()))
  5492. parser->normalizeExpression($5, type_unicode, false);
  5493. else
  5494. parser->normalizeExpression($5, type_string, false);
  5495. $$.setExpr(createValue(no_regex_find, makeBoolType(), $3.getExpr(), $5.getExpr(), $6.getExpr()));
  5496. }
  5497. | REGEXFIND '(' expression ',' expression ',' expression regexOpt ')'
  5498. {
  5499. parser->normalizeExpression($3, type_stringorunicode, false);
  5500. Owned<ITypeInfo> subType;
  5501. if(isUnicodeType($3.queryExprType()))
  5502. {
  5503. parser->normalizeExpression($5, type_unicode, false);
  5504. subType.setown(makeUnicodeType(UNKNOWN_LENGTH, 0));
  5505. }
  5506. else
  5507. {
  5508. parser->normalizeExpression($5, type_string, false);
  5509. subType.setown(makeStringType(UNKNOWN_LENGTH));
  5510. }
  5511. parser->normalizeExpression($7, type_int, false);
  5512. $$.setExpr(createValue(no_regex_find, subType.getLink(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr()));
  5513. }
  5514. | REGEXREPLACE '(' expression ',' expression ',' expression regexOpt ')'
  5515. {
  5516. parser->normalizeExpression($3, type_stringorunicode, false);
  5517. Owned<ITypeInfo> retType;
  5518. if(isUnicodeType($3.queryExprType()))
  5519. {
  5520. parser->normalizeExpression($5, type_unicode, false);
  5521. parser->normalizeExpression($7, type_unicode, false);
  5522. retType.setown(makeUnicodeType(UNKNOWN_LENGTH, 0));
  5523. }
  5524. else
  5525. {
  5526. parser->normalizeExpression($5, type_string, false);
  5527. parser->normalizeExpression($7, type_string, false);
  5528. retType.setown(makeStringType(UNKNOWN_LENGTH));
  5529. }
  5530. $$.setExpr(createValue(no_regex_replace, retType.getLink(), $3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr()));
  5531. }
  5532. | ASSTRING '(' expression ')'
  5533. {
  5534. parser->normalizeExpression($3);
  5535. IHqlExpression *expr = $3.getExpr();
  5536. $$.setExpr(createValue(no_asstring, makeStringType(expr->queryType()->getSize(),NULL,NULL), expr));
  5537. }
  5538. | TRANSFER '(' expression ',' scalarType ')'
  5539. {
  5540. parser->normalizeExpression($3);
  5541. IHqlExpression *expr = $3.getExpr();
  5542. ITypeInfo *exprType = expr->queryType();
  5543. ITypeInfo *type = $5.getType();
  5544. if ((exprType->getSize() != UNKNOWN_LENGTH) && (exprType->getSize() < type->getSize()) && type->getSize() != UNKNOWN_LENGTH)
  5545. parser->reportError(ERR_TYPETRANS_LARGERTYPE, $5, "Type transfer: target type in is larger than source type");
  5546. $$.setExpr(createTypeTransfer(expr, type));
  5547. }
  5548. | TRANSFER '(' dataRow ',' scalarType ')'
  5549. {
  5550. //User had better know what they are doing
  5551. $$.setExpr(createTypeTransfer($3.getExpr(), $5.getType()), $1);
  5552. }
  5553. | TRANSFER '(' dataSet ',' scalarType ')'
  5554. {
  5555. //User had better know what they are doing
  5556. $$.setExpr(createTypeTransfer($3.getExpr(), $5.getType()), $1);
  5557. }
  5558. | MAX '(' startTopFilter ',' expression aggregateFlags ')' endTopFilter
  5559. {
  5560. parser->normalizeExpression($5);
  5561. IHqlExpression *e5 = $5.getExpr();
  5562. $$.setExpr(createValue(no_max, e5->getType(), $3.getExpr(), e5, $6.getExpr()));
  5563. }
  5564. | MAX '(' GROUP ',' expression ')'
  5565. {
  5566. parser->normalizeExpression($5);
  5567. IHqlExpression *e5 = $5.getExpr();
  5568. $$.setExpr(createValue(no_maxgroup, e5->getType(), e5));
  5569. }
  5570. | MIN '(' startTopFilter ',' expression aggregateFlags ')' endTopFilter
  5571. {
  5572. parser->normalizeExpression($5);
  5573. IHqlExpression *e5 = $5.getExpr();
  5574. $$.setExpr(createValue(no_min, e5->getType(), $3.getExpr(), e5, $6.getExpr()));
  5575. }
  5576. | MIN '(' GROUP ',' expression ')'
  5577. {
  5578. parser->normalizeExpression($5);
  5579. IHqlExpression *e5 = $5.getExpr();
  5580. $$.setExpr(createValue(no_mingroup, e5->getType(), e5));
  5581. }
  5582. | EVALUATE '(' evaluateTopFilter ',' expression ')' endTopFilter
  5583. {
  5584. parser->normalizeExpression($5);
  5585. OwnedHqlExpr expr = $5.getExpr();
  5586. OwnedHqlExpr scope = $3.getExpr();
  5587. $$.setExpr(createValue(no_evaluate, expr->getType(), LINK(scope), LINK(expr)));
  5588. }
  5589. | SUM '(' startTopFilter ',' expression aggregateFlags ')' endTopFilter
  5590. {
  5591. parser->normalizeExpression($5);
  5592. Owned<ITypeInfo> temp = parser->checkPromoteNumeric($5, true);
  5593. OwnedHqlExpr value = $5.getExpr();
  5594. Owned<ITypeInfo> type = getSumAggType(value);
  5595. $$.setExpr(createValue(no_sum, LINK(type), $3.getExpr(), ensureExprType(value, type), $6.getExpr()));
  5596. }
  5597. | SUM '(' GROUP ',' expression optExtraFilter ')'
  5598. {
  5599. parser->normalizeExpression($5);
  5600. Owned<ITypeInfo> temp = parser->checkPromoteNumeric($5, true);
  5601. OwnedHqlExpr value = $5.getExpr();
  5602. Owned<ITypeInfo> type = getSumAggType(value);
  5603. $$.setExpr(createValue(no_sumgroup, LINK(type), ensureExprType(value, type), $6.getExpr()));
  5604. }
  5605. | AVE '(' startTopFilter ',' expression aggregateFlags ')' endTopFilter
  5606. {
  5607. parser->normalizeExpression($5, type_numeric, false);
  5608. $$.setExpr(createValue(no_ave, makeRealType(8), $3.getExpr(), $5.getExpr(), $6.getExpr()));
  5609. }
  5610. | AVE '(' GROUP ',' expression optExtraFilter')'
  5611. {
  5612. parser->normalizeExpression($5, type_numeric, false);
  5613. $$.setExpr(createValue(no_avegroup, makeRealType(8), $5.getExpr(), $6.getExpr()));
  5614. }
  5615. | VARIANCE '(' startTopFilter ',' expression aggregateFlags ')' endTopFilter
  5616. {
  5617. parser->normalizeExpression($5, type_numeric, false);
  5618. $$.setExpr(createValue(no_variance, makeRealType(8), $3.getExpr(), $5.getExpr(), $6.getExpr()));
  5619. }
  5620. | VARIANCE '(' GROUP ',' expression optExtraFilter')'
  5621. {
  5622. parser->normalizeExpression($5, type_numeric, false);
  5623. $$.setExpr(createValue(no_vargroup, makeRealType(8), $5.getExpr(), $6.getExpr()));
  5624. }
  5625. | COVARIANCE '(' startTopFilter ',' expression ',' expression aggregateFlags ')' endTopFilter
  5626. {
  5627. parser->normalizeExpression($5, type_numeric, false);
  5628. parser->normalizeExpression($7, type_numeric, false);
  5629. $$.setExpr(createValue(no_covariance, makeRealType(8), $3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr()));
  5630. }
  5631. | COVARIANCE '(' GROUP ',' expression ',' expression optExtraFilter')'
  5632. {
  5633. parser->normalizeExpression($5, type_numeric, false);
  5634. parser->normalizeExpression($7, type_numeric, false);
  5635. $$.setExpr(createValue(no_covargroup, makeRealType(8), $5.getExpr(), $7.getExpr(), $8.getExpr()));
  5636. }
  5637. | CORRELATION '(' startTopFilter ',' expression ',' expression aggregateFlags ')' endTopFilter
  5638. {
  5639. parser->normalizeExpression($5, type_numeric, false);
  5640. parser->normalizeExpression($7, type_numeric, false);
  5641. $$.setExpr(createValue(no_correlation, makeRealType(8), $3.getExpr(), $5.getExpr(), $7.getExpr(), $8.getExpr()));
  5642. }
  5643. | CORRELATION '(' GROUP ',' expression ',' expression optExtraFilter')'
  5644. {
  5645. parser->normalizeExpression($5, type_numeric, false);
  5646. parser->normalizeExpression($7, type_numeric, false);
  5647. $$.setExpr(createValue(no_corrgroup, makeRealType(8), $5.getExpr(), $7.getExpr(), $8.getExpr()));
  5648. }
  5649. | WHICH conditions {
  5650. $$.setExpr(createList(no_which, LINK(parser->uint4Type), $2.getExpr()));
  5651. }
  5652. | REJECTED conditions
  5653. {
  5654. $$.setExpr(createList(no_rejected, LINK(parser->uint4Type), $2.getExpr()));
  5655. }
  5656. | SIZEOF '(' sizeof_type_target optMaxMin ')'
  5657. {
  5658. ITypeInfo* type = $3.getType();
  5659. OwnedHqlExpr max = $4.getExpr();
  5660. if (!max)
  5661. parser->checkSizeof(type,$1);
  5662. //rather easier to create a dummy argument with the correct type.
  5663. $$.setExpr(createValue(no_sizeof, LINK(parser->uint4Type), createValue(no_none, type), max.getClear()));
  5664. }
  5665. | SIZEOF '(' sizeof_expr_target optMaxMin ')'
  5666. {
  5667. OwnedHqlExpr arg = $3.getExpr();
  5668. OwnedHqlExpr max = $4.getExpr();
  5669. if (!max)
  5670. parser->checkSizeof(arg,$1);
  5671. $$.setExpr(createValue(no_sizeof, LINK(parser->uint4Type), arg.getClear(), max.getClear()));
  5672. }
  5673. | SIZEOF '(' error ')'
  5674. {
  5675. parser->reportError(ERR_SIZEOF_WRONGPARAM, $1,"Illegal parameter for SIZEOF");
  5676. $$.setExpr(createConstant(1), $1);
  5677. }
  5678. | RANK '(' expression ',' expression optAscDesc ')'
  5679. {
  5680. parser->normalizeExpression($3);
  5681. parser->normalizeExpression($5, type_set, false);
  5682. $$.setExpr(createValue(no_rank, LINK(parser->uint4Type), $3.getExpr(), $5.getExpr(), $6.getExpr()));
  5683. }
  5684. | RANKED '(' expression ',' expression optAscDesc')'
  5685. {
  5686. parser->normalizeExpression($3);
  5687. parser->normalizeExpression($5, type_set, false);
  5688. $$.setExpr(createValue(no_ranked, LINK(parser->uint4Type), $3.getExpr(), $5.getExpr(), $6.getExpr()));
  5689. }
  5690. | COUNT {
  5691. $$.setExpr(parser->getActiveCounter($1));
  5692. parser->reportWarning(SeverityError, ERR_COUNTER_NOT_COUNT, $1.pos, "Use of COUNT instead of COUNTER is deprecated");
  5693. }
  5694. | COUNTER {
  5695. $$.setExpr(parser->getActiveCounter($1));
  5696. }
  5697. | ISNULL '(' expression ')'
  5698. {
  5699. parser->normalizeExpression($3);
  5700. $$.setExpr(createValue(no_is_null, makeBoolType(), $3.getExpr()));
  5701. }
  5702. | ISVALID '(' expression ')'
  5703. {
  5704. parser->normalizeExpression($3);
  5705. $$.setExpr(createValue(no_is_valid, makeBoolType(), $3.getExpr()));
  5706. }
  5707. | OMITTED '(' goodObject ')'
  5708. {
  5709. parser->reportError(ERR_EXPECTED, $1, "Not yet supported - needs more work");
  5710. parser->normalizeExpression($3);
  5711. OwnedHqlExpr value = $3.getExpr();
  5712. if (value->getOperator() != no_param)
  5713. parser->reportError(ERR_EXPECTED, $3, "Expected a parameter as the argument");
  5714. $$.setExpr(createValue(no_isomitted, makeBoolType(), value.getClear()));
  5715. }
  5716. | FAILCODE { $$.setExpr(createValue(no_failcode, makeIntType(4, true))); }
  5717. | FAILMESSAGE { $$.setExpr(createValue(no_failmessage, makeStringType(UNKNOWN_LENGTH, NULL, NULL))); }
  5718. | FAILMESSAGE '(' expression ')'
  5719. {
  5720. parser->normalizeExpression($3, type_string, false);
  5721. $$.setExpr(createValue(no_failmessage, makeStringType(UNKNOWN_LENGTH, NULL, NULL), $3.getExpr()));
  5722. }
  5723. | EVENTNAME { $$.setExpr(createValue(no_eventname, makeStringType(UNKNOWN_LENGTH, NULL, NULL))); }
  5724. | EVENTEXTRA { $$.setExpr(createValue(no_eventextra, makeStringType(UNKNOWN_LENGTH, NULL, NULL))); }
  5725. | EVENTEXTRA '(' expression ')'
  5726. {
  5727. parser->normalizeExpression($3, type_string, false);
  5728. $$.setExpr(createValue(no_eventextra, makeStringType(UNKNOWN_LENGTH, NULL, NULL), $3.getExpr()));
  5729. }
  5730. | TOK_ERROR '(' expression ',' expression ')'
  5731. {
  5732. parser->normalizeExpression($3, type_int, false);
  5733. parser->normalizeExpression($5, type_string, false);
  5734. $$.setExpr(createValue(no_fail, makeAnyType(), $3.getExpr(), $5.getExpr()));
  5735. }
  5736. | TOK_ERROR '(' expression ')'
  5737. {
  5738. parser->checkIntegerOrString($3);
  5739. $$.setExpr(createValue(no_fail, makeAnyType(), $3.getExpr()));
  5740. }
  5741. | TOK_ERROR '(' ')' {
  5742. $$.setExpr(createValue(no_fail, makeAnyType()));
  5743. }
  5744. | FAIL '(' scalarType ',' expression ',' expression ')'
  5745. {
  5746. $3.release();
  5747. parser->normalizeExpression($5, type_int, false);
  5748. parser->normalizeExpression($7, type_string, false);
  5749. $$.setExpr(createValue(no_fail, makeAnyType(), $5.getExpr(), $7.getExpr()));
  5750. }
  5751. | FAIL '(' scalarType ',' expression ')'
  5752. {
  5753. $3.release();
  5754. parser->normalizeExpression($5);
  5755. parser->checkIntegerOrString($5);
  5756. $$.setExpr(createValue(no_fail, makeAnyType(), $5.getExpr()));
  5757. }
  5758. | FAIL '(' scalarType ')'
  5759. {
  5760. $3.release();
  5761. $$.setExpr(createValue(no_fail, makeAnyType()));
  5762. }
  5763. | SKIP {
  5764. if (!parser->curTransform)
  5765. parser->reportError(ERR_PARSER_CANNOTRECOVER,$1,"SKIP is only valid inside a TRANSFORM");
  5766. $$.setExpr(createValue(no_skip, makeAnyType()));
  5767. }
  5768. | FROMUNICODE '(' expression ',' expression ')'
  5769. {
  5770. parser->normalizeExpression($3, type_unicode, false);
  5771. parser->normalizeExpression($5, type_string, false);
  5772. $$.setExpr(createValue(no_fromunicode, makeDataType(UNKNOWN_LENGTH), $3.getExpr(), $5.getExpr()));
  5773. }
  5774. | TOUNICODE '(' expression ',' expression ')'
  5775. {
  5776. parser->normalizeExpression($3);
  5777. parser->ensureData($3);
  5778. parser->normalizeExpression($5, type_string, false);
  5779. $$.setExpr(createValue(no_tounicode, makeUnicodeType(UNKNOWN_LENGTH, 0), $3.getExpr(), $5.getExpr()));
  5780. }
  5781. | KEYUNICODE '(' expression ')'
  5782. {
  5783. parser->normalizeExpression($3, type_unicode, false);
  5784. $$.setExpr(createValue(no_keyunicode, makeDataType(UNKNOWN_LENGTH), $3.getExpr(), createConstant($3.queryExprType()->queryLocale()->str()), createConstant(3)));
  5785. }
  5786. | KEYUNICODE '(' expression ',' expression ')'
  5787. {
  5788. parser->normalizeExpression($3, type_unicode, false);
  5789. parser->normalizeExpression($5);
  5790. parser->ensureString($5);
  5791. Owned<IHqlExpression> lexpr = $5.getExpr();
  5792. Owned<ITypeInfo> ltype = lexpr->getType();
  5793. Owned<IHqlExpression> locale = (ltype->getTypeCode() == type_varstring) ? lexpr.getLink() : createValue(no_implicitcast, makeVarStringType(ltype->getStringLen()), lexpr.getLink());
  5794. $$.setExpr(createValue(no_keyunicode, makeDataType(UNKNOWN_LENGTH), $3.getExpr(), locale.getLink(), createConstant(3)));
  5795. }
  5796. | KEYUNICODE '(' expression ',' ',' expression ')'
  5797. {
  5798. parser->normalizeExpression($3, type_unicode, false);
  5799. parser->normalizeExpression($6, type_int, false);
  5800. $$.setExpr(createValue(no_keyunicode, makeDataType(UNKNOWN_LENGTH), $3.getExpr(), createConstant($3.queryExprType()->queryLocale()->str()), $6.getExpr()));
  5801. }
  5802. | KEYUNICODE '(' expression ',' expression ',' expression ')'
  5803. {
  5804. parser->normalizeExpression($3, type_unicode, false);
  5805. parser->normalizeExpression($5);
  5806. parser->normalizeExpression($7, type_int, false);
  5807. parser->ensureString($5);
  5808. Owned<IHqlExpression> lexpr = $5.getExpr();
  5809. Owned<ITypeInfo> ltype = lexpr->getType();
  5810. Owned<IHqlExpression> locale = (ltype->getTypeCode() == type_varstring) ? lexpr.getLink() : createValue(no_implicitcast, makeVarStringType(ltype->getStringLen()), lexpr.getLink());
  5811. $$.setExpr(createValue(no_keyunicode, makeDataType(UNKNOWN_LENGTH), $3.getExpr(), locale.getLink(), $7.getExpr()));
  5812. }
  5813. | MATCHED '(' patternReference ')'
  5814. {
  5815. $$.setExpr(createValue(no_matched, makeBoolType(), $3.getExpr())); //, parser->createUniqueId()));
  5816. }
  5817. | MATCHTEXT '(' patternReference ')'
  5818. {
  5819. $$.setExpr(createValue(no_matchtext, makeStringType(UNKNOWN_LENGTH, NULL, NULL), $3.getExpr())); //, parser->createUniqueId()));
  5820. }
  5821. | MATCHUNICODE '(' patternReference ')'
  5822. {
  5823. $$.setExpr(createValue(no_matchunicode, makeUnicodeType(UNKNOWN_LENGTH, NULL), $3.getExpr())); //, parser->createUniqueId()));
  5824. }
  5825. | MATCHUTF8 '(' patternReference ')'
  5826. {
  5827. $$.setExpr(createValue(no_matchutf8, makeUtf8Type(UNKNOWN_LENGTH, NULL), $3.getExpr())); //, parser->createUniqueId()));
  5828. }
  5829. | MATCHLENGTH '(' patternReference ')'
  5830. {
  5831. $$.setExpr(createValue(no_matchlength, LINK(parser->uint4Type), $3.getExpr())); //, parser->createUniqueId()));
  5832. }
  5833. | MATCHPOSITION '(' patternReference ')'
  5834. {
  5835. $$.setExpr(createValue(no_matchposition, LINK(parser->uint4Type), $3.getExpr())); //, parser->createUniqueId()));
  5836. }
  5837. | MATCHED
  5838. {
  5839. $$.setExpr(createValue(no_matched, makeBoolType())); //, parser->createUniqueId()));
  5840. }
  5841. | MATCHTEXT
  5842. {
  5843. $$.setExpr(createValue(no_matchtext, makeStringType(UNKNOWN_LENGTH, NULL, NULL))); //, parser->createUniqueId()));
  5844. }
  5845. | MATCHUNICODE
  5846. {
  5847. $$.setExpr(createValue(no_matchunicode, makeUnicodeType(UNKNOWN_LENGTH, NULL))); //, parser->createUniqueId()));
  5848. }
  5849. | MATCHUTF8
  5850. {
  5851. $$.setExpr(createValue(no_matchutf8, makeUtf8Type(UNKNOWN_LENGTH, NULL))); //, parser->createUniqueId()));
  5852. }
  5853. | MATCHLENGTH
  5854. {
  5855. $$.setExpr(createValue(no_matchlength, LINK(parser->uint4Type))); //, parser->createUniqueId()));
  5856. }
  5857. | MATCHPOSITION
  5858. {
  5859. $$.setExpr(createValue(no_matchposition, LINK(parser->uint4Type))); //, parser->createUniqueId()));
  5860. }
  5861. | MATCHTEXT '(' expression ')'
  5862. {
  5863. parser->normalizeExpression($3);
  5864. $$.setExpr(parser->createCheckMatchAttr($3, type_string));
  5865. $$.setPosition($1);
  5866. }
  5867. | MATCHUNICODE '(' expression ')'
  5868. {
  5869. parser->normalizeExpression($3);
  5870. $$.setExpr(parser->createCheckMatchAttr($3, type_unicode));
  5871. $$.setPosition($1);
  5872. }
  5873. | MATCHUTF8 '(' expression ')'
  5874. {
  5875. parser->normalizeExpression($3);
  5876. $$.setExpr(parser->createCheckMatchAttr($3, type_utf8));
  5877. $$.setPosition($1);
  5878. }
  5879. | MATCHTEXT '(' dataRow ')'
  5880. {
  5881. $$.setExpr(parser->createCheckMatchAttr($3, type_string));
  5882. $$.setPosition($1);
  5883. }
  5884. | MATCHUNICODE '(' dataRow ')'
  5885. {
  5886. $$.setExpr(parser->createCheckMatchAttr($3, type_unicode));
  5887. $$.setPosition($1);
  5888. }
  5889. | MATCHUTF8 '(' dataRow ')'
  5890. {
  5891. $$.setExpr(parser->createCheckMatchAttr($3, type_utf8));
  5892. $$.setPosition($1);
  5893. }
  5894. | ROWDIFF '(' dataRow ',' dataRow optCount ')'
  5895. {
  5896. $$.setExpr(createValue(no_rowdiff, makeStringType(UNKNOWN_LENGTH, NULL, NULL), $3.getExpr(), $5.getExpr(), $6.getExpr()));
  5897. }
  5898. | WORKUNIT { $$.setExpr(createValue(no_wuid, makeStringType(UNKNOWN_LENGTH, NULL, NULL))); }
  5899. | XMLDECODE '(' expression ')'
  5900. {
  5901. parser->normalizeExpression($3, type_stringorunicode, false);
  5902. ITypeInfo * type = isUnicodeType($3.queryExprType()) ? makeUnicodeType(UNKNOWN_LENGTH, NULL) : makeStringType(UNKNOWN_LENGTH, NULL, NULL);
  5903. $$.setExpr(createValue(no_xmldecode, type, $3.getExpr()));
  5904. }
  5905. | XMLENCODE '(' expression xmlEncodeFlags ')'
  5906. {
  5907. parser->normalizeExpression($3, type_stringorunicode, false);
  5908. ITypeInfo * type = isUnicodeType($3.queryExprType()) ? makeUnicodeType(UNKNOWN_LENGTH, NULL) : makeStringType(UNKNOWN_LENGTH, NULL, NULL);
  5909. $$.setExpr(createValue(no_xmlencode, type, $3.getExpr(), $4.getExpr()));
  5910. }
  5911. | XMLTEXT '(' expression ')'
  5912. {
  5913. parser->normalizeExpression($3, type_string, false);
  5914. parser->validateXPath($3);
  5915. $$.setExpr(createValue(no_xmltext, makeStringType(UNKNOWN_LENGTH, NULL, NULL), $3.getExpr(), parser->createUniqueId()));
  5916. }
  5917. | XMLUNICODE '(' expression ')'
  5918. {
  5919. parser->normalizeExpression($3, type_string, false);
  5920. parser->validateXPath($3);
  5921. $$.setExpr(createValue(no_xmlunicode, makeUnicodeType(UNKNOWN_LENGTH, NULL), $3.getExpr(), parser->createUniqueId()));
  5922. }
  5923. | KEYED '(' expression ')'
  5924. {
  5925. parser->normalizeExpression($3);
  5926. IHqlExpression * e = $3.getExpr();
  5927. $$.setExpr(createValue(no_assertkeyed, e->getType(), e));
  5928. }
  5929. | KEYED '(' expression ',' OPT ')'
  5930. {
  5931. parser->normalizeExpression($3);
  5932. IHqlExpression * e = $3.getExpr();
  5933. $$.setExpr(createValue(no_assertkeyed, e->getType(), e, createAttribute(extendAtom)));
  5934. }
  5935. | STEPPED '(' expression ')'
  5936. {
  5937. parser->normalizeExpression($3);
  5938. IHqlExpression * e = $3.getExpr();
  5939. $$.setExpr(createValue(no_assertstepped, e->getType(), e));
  5940. }
  5941. | WILD '(' expression ')'
  5942. {
  5943. parser->normalizeExpression($3);
  5944. IHqlExpression * e = $3.getExpr();
  5945. if (e->getOperator() != no_select)
  5946. parser->reportError(ERR_EXPECTED, $2, "WILD requires a key field as a parameter");
  5947. $$.setExpr(createValue(no_assertwild, makeBoolType(), e));
  5948. }
  5949. | TOK_CATCH '(' expression ',' expression ')'
  5950. {
  5951. parser->normalizeExpression($3);
  5952. parser->normalizeExpression($5);
  5953. ITypeInfo * type = parser->promoteToSameType($3, $5);
  5954. $$.setExpr(createValue(no_catch, type, $3.getExpr(), $5.getExpr()));
  5955. }
  5956. | __COMPOUND__ '(' action ',' expression ')'
  5957. {
  5958. parser->normalizeExpression($5);
  5959. //Not public! only for internal testing.
  5960. $$.setExpr(createCompound($3.getExpr(), $5.getExpr()));
  5961. $$.setPosition($1);
  5962. }
  5963. | WHEN '(' expression ',' action ')'
  5964. {
  5965. parser->normalizeExpression($3);
  5966. $$.setExpr(createCompound($5.getExpr(), $3.getExpr()));
  5967. $$.setPosition($1);
  5968. }
  5969. | __COMMON__ '(' expression ')'
  5970. {
  5971. parser->normalizeExpression($3);
  5972. $$.setExpr(createAliasOwn($3.getExpr(), NULL));
  5973. $$.setPosition($1);
  5974. }
  5975. | CLUSTERSIZE
  5976. {
  5977. $$.setExpr(createValue(no_clustersize, makeIntType(4, false)));
  5978. $$.setPosition($1);
  5979. }
  5980. | CHOOSENALL
  5981. {
  5982. $$.setExpr(createConstant(CHOOSEN_ALL_LIMIT));
  5983. $$.setPosition($1);
  5984. }
  5985. | WORKUNIT '(' expression ',' simpleType ')'
  5986. {
  5987. parser->normalizeExpression($3, type_any, true);
  5988. OwnedHqlExpr seq = $3.getExpr();
  5989. OwnedHqlExpr name;
  5990. if (isStringType(seq->queryType()))
  5991. {
  5992. name.set(seq);
  5993. seq.setown(createConstant(0));
  5994. }
  5995. if (name)
  5996. name.setown(createAttribute(namedAtom, LINK(name)));
  5997. $$.setExpr(createValue(no_getresult, $5.getType(), createAttribute(sequenceAtom, LINK(seq)), LINK(name)));
  5998. $$.setPosition($1);
  5999. }
  6000. | LOCAL '(' expression ')'
  6001. {
  6002. parser->normalizeExpression($3);
  6003. IHqlExpression * expr = $3.getExpr();
  6004. $$.setExpr(createValue(no_forcelocal, expr->getType(), expr));
  6005. $$.setPosition($1);
  6006. }
  6007. | NOLOCAL '(' expression ')'
  6008. {
  6009. parser->normalizeExpression($3);
  6010. IHqlExpression * expr = $3.getExpr();
  6011. $$.setExpr(createValue(no_forcenolocal, expr->getType(), expr));
  6012. $$.setPosition($1);
  6013. }
  6014. | THISNODE '(' expression ')'
  6015. {
  6016. parser->normalizeExpression($3);
  6017. IHqlExpression * expr = $3.getExpr();
  6018. $$.setExpr(createValue(no_thisnode, expr->getType(), expr));
  6019. $$.setPosition($1);
  6020. }
  6021. | COUNT '(' expressionList ')'
  6022. {
  6023. OwnedHqlExpr list = parser->createListFromExpressionList($3);
  6024. $$.setExpr(createValue(no_countlist, LINK(parser->defaultIntegralType), LINK(list)));
  6025. $$.setPosition($1);
  6026. }
  6027. | EXISTS '(' expressionList ')'
  6028. {
  6029. if (parser->isSingleValuedExpressionList($3))
  6030. parser->reportWarning(WRN_SILLY_EXISTS,$1.pos,"EXISTS() on a scalar expression is always true, was this intended?");
  6031. OwnedHqlExpr list = parser->createListFromExpressionList($3);
  6032. $$.setExpr(createValue(no_existslist, makeBoolType(), LINK(list)));
  6033. $$.setPosition($1);
  6034. }
  6035. | SUM '(' expressionList ')'
  6036. {
  6037. OwnedHqlExpr list = parser->createListFromExpressionList($3);
  6038. ITypeInfo * elemType = parser->queryElementType($3, list);
  6039. Owned<ITypeInfo> sumType = getSumAggType(elemType);
  6040. $$.setExpr(createValue(no_sumlist, LINK(sumType), LINK(list)));
  6041. $$.setPosition($1);
  6042. }
  6043. | MAX '(' expressionList ')'
  6044. {
  6045. OwnedHqlExpr list = parser->createListFromExpressionList($3);
  6046. ITypeInfo * elemType = parser->queryElementType($3, list);
  6047. $$.setExpr(createValue(no_maxlist, LINK(elemType), LINK(list)));
  6048. $$.setPosition($1);
  6049. }
  6050. | MIN '(' expressionList ')'
  6051. {
  6052. OwnedHqlExpr list = parser->createListFromExpressionList($3);
  6053. ITypeInfo * elemType = parser->queryElementType($3, list);
  6054. $$.setExpr(createValue(no_minlist, LINK(elemType), LINK(list)));
  6055. $$.setPosition($1);
  6056. }
  6057. | AVE '(' expressionList ')'
  6058. {
  6059. OwnedHqlExpr list = parser->createListFromExpressionList($3);
  6060. $$.setExpr(parser->createAveList($3, list));
  6061. $$.setPosition($1);
  6062. }
  6063. | NAMEOF '(' dataSet ')'
  6064. {
  6065. $$.setExpr(createValue(no_nameof, makeStringType(UNKNOWN_LENGTH, NULL, NULL), $3.getExpr()));
  6066. }
  6067. | UNICODEORDER '(' expression ',' expression ')'
  6068. {
  6069. parser->normalizeExpression($3, type_unicode, false);
  6070. parser->normalizeExpression($5, type_unicode, false);
  6071. ::Release(parser->checkPromoteType($3, $5));
  6072. IAtom * locale = parser->ensureCommonLocale($3, $5);
  6073. $$.setExpr(createValue(no_unicodeorder, makeIntType(4, true), $3.getExpr(), $5.getExpr(), createConstant(locale->str()), createConstant(3)));
  6074. }
  6075. | UNICODEORDER '(' expression ',' expression ',' expression ')'
  6076. {
  6077. parser->normalizeExpression($3, type_unicode, false);
  6078. parser->normalizeExpression($5, type_unicode, false);
  6079. parser->normalizeExpression($7);
  6080. parser->ensureString($7);
  6081. ::Release(parser->checkPromoteType($3, $5));
  6082. Owned<IHqlExpression> lexpr = $7.getExpr();
  6083. Owned<ITypeInfo> ltype = lexpr->getType();
  6084. Owned<IHqlExpression> locale = (ltype->getTypeCode() == type_varstring) ? lexpr.getLink() : createValue(no_implicitcast, makeVarStringType(ltype->getStringLen()), lexpr.getLink());
  6085. $$.setExpr(createValue(no_unicodeorder, makeIntType(4, true), $3.getExpr(), $5.getExpr(), locale.getLink(), createConstant(3)));
  6086. }
  6087. | UNICODEORDER '(' expression ',' expression ',' ',' expression ')'
  6088. {
  6089. parser->normalizeExpression($3, type_unicode, false);
  6090. parser->normalizeExpression($5, type_unicode, false);
  6091. IAtom * locale = parser->ensureCommonLocale($3, $5);
  6092. parser->normalizeExpression($8, type_int, false);
  6093. ::Release(parser->checkPromoteType($3, $5));
  6094. $$.setExpr(createValue(no_unicodeorder, makeIntType(4, true), $3.getExpr(), $5.getExpr(), createConstant(locale->str()), $8.getExpr()));
  6095. }
  6096. | UNICODEORDER '(' expression ',' expression ',' expression ',' expression ')'
  6097. {
  6098. parser->normalizeExpression($3, type_unicode, false);
  6099. parser->normalizeExpression($5, type_unicode, false);
  6100. parser->normalizeExpression($7);
  6101. parser->normalizeExpression($9, type_int, false);
  6102. parser->ensureString($7);
  6103. ::Release(parser->checkPromoteType($3, $5));
  6104. Owned<IHqlExpression> lexpr = $7.getExpr();
  6105. Owned<ITypeInfo> ltype = lexpr->getType();
  6106. Owned<IHqlExpression> locale = (ltype->getTypeCode() == type_varstring) ? lexpr.getLink() : createValue(no_implicitcast, makeVarStringType(ltype->getStringLen()), lexpr.getLink());
  6107. $$.setExpr(createValue(no_unicodeorder, makeIntType(4, true), $3.getExpr(), $5.getExpr(), locale.getLink(), $9.getExpr()));
  6108. }
  6109. | '[' beginList sortList ']'
  6110. {
  6111. HqlExprArray sortItems;
  6112. parser->endList(sortItems);
  6113. OwnedHqlExpr fields = parser->processSortList($3, no_list, NULL, sortItems, NULL, NULL);
  6114. $$.setExpr(fields.getClear(), $1);
  6115. }
  6116. | '[' ']' {
  6117. $$.setExpr(createList(no_list, makeSetType(NULL), NULL));
  6118. $$.setPosition($1);
  6119. }
  6120. | ALL {
  6121. $$.setExpr(createValue(no_all, makeSetType(NULL), NULL));
  6122. $$.setPosition($1);
  6123. }
  6124. | SET '(' startTopFilter ',' expression ')' endTopFilter
  6125. {
  6126. parser->normalizeExpression($5, type_scalar, false);
  6127. IHqlExpression * ds = $3.getExpr();
  6128. IHqlExpression * field = $5.getExpr();
  6129. $$.setExpr(createValue(no_createset, makeSetType(field->getType()), ds, field));
  6130. $$.setPosition($1);
  6131. }
  6132. | GETENV '(' expression ')'
  6133. {
  6134. parser->normalizeExpression($3, type_stringorunicode, false);
  6135. $$.setExpr(createValue(no_getenv, makeVarStringType(UNKNOWN_LENGTH), $3.getExpr()), $1);
  6136. }
  6137. | GETENV '(' expression ',' expression ')'
  6138. {
  6139. parser->normalizeExpression($3, type_stringorunicode, false);
  6140. parser->normalizeExpression($5, type_stringorunicode, false);
  6141. $$.setExpr(createValue(no_getenv, makeVarStringType(UNKNOWN_LENGTH), $3.getExpr(), $5.getExpr()), $1);
  6142. }
  6143. | __STAND_ALONE__
  6144. {
  6145. $$.setExpr(createValue(no_debug_option_value, makeBoolType(), createConstant("standAloneExe")));
  6146. }
  6147. | __DEBUG__ '(' stringConstExpr ')'
  6148. {
  6149. $$.setExpr(createValue(no_debug_option_value, makeStringType(UNKNOWN_LENGTH, NULL), $3.getExpr()), $1);
  6150. }
  6151. | __DEBUG__ '(' stringConstExpr ',' simpleType ')'
  6152. {
  6153. $$.setExpr(createValue(no_debug_option_value, $5.getType(), $3.getExpr()), $1);
  6154. }
  6155. | __PLATFORM__
  6156. {
  6157. OwnedHqlExpr option = createConstant("targetClusterType");
  6158. $$.setExpr(createValue(no_debug_option_value, makeStringType(UNKNOWN_LENGTH, NULL), option.getClear()), $1);
  6159. }
  6160. ;
  6161. optCount
  6162. : { $$.setNullExpr(); }
  6163. | ',' COUNT { $$.setExpr(createAttribute(countAtom)); }
  6164. ;
  6165. evaluateTopFilter
  6166. : dataRow {
  6167. parser->pushTopScope($1.queryExpr());
  6168. $$.setExpr($1.getExpr());
  6169. parser->insideEvaluate = true;
  6170. }
  6171. ;
  6172. alienTypeInstance
  6173. : qualifiedTypeId
  6174. {
  6175. parser->beginFunctionCall($1); //
  6176. }
  6177. optParams // alien type
  6178. {
  6179. OwnedHqlExpr alienExpr;
  6180. OwnedHqlExpr args = $3.getExpr();
  6181. if ($1.queryExpr()->isFunction())
  6182. {
  6183. alienExpr.setown(parser->bindParameters($1, args.getClear()));
  6184. }
  6185. else
  6186. {
  6187. if (args)
  6188. parser->reportError(ERR_TYPE_NOPARAMNEEDED, $1, "Type does not require parameters: %s", $1.queryExpr()->queryName()->str());
  6189. alienExpr.setown($1.getExpr());
  6190. }
  6191. $$.setType(makeModifier(alienExpr->getType(), typemod_indirect, LINK(alienExpr)));
  6192. $$.setPosition($1);
  6193. }
  6194. ;
  6195. sizeof_type_target
  6196. : simpleType
  6197. | setType
  6198. | alienTypeInstance
  6199. ;
  6200. sizeof_expr_target
  6201. : expression
  6202. {
  6203. parser->normalizeExpression($1);
  6204. $$.inherit($1);
  6205. }
  6206. | dataSet
  6207. | dataRow
  6208. | enumTypeId
  6209. | recordDef
  6210. | fieldSelectedFromRecord
  6211. {
  6212. OwnedHqlExpr rhs = $1.getExpr();
  6213. IHqlExpression * field = queryFieldFromSelect(rhs);
  6214. //This way to ensure backward compatibility of the eclcrc
  6215. $$.setExpr(createSelectExpr(getActiveTableSelector(), LINK(field)));
  6216. $$.setPosition($1);
  6217. }
  6218. ;
  6219. fieldSelectedFromRecord
  6220. : recordScope VALUE_ID leaveScope
  6221. {
  6222. $$.setExpr(parser->createSelect($1.getExpr(), $2.getExpr(), $1), $1);
  6223. }
  6224. | recordScope DATASET_ID leaveScope
  6225. {
  6226. $$.setExpr(parser->createSelect($1.getExpr(), $2.getExpr(), $1), $1);
  6227. }
  6228. | recordScope startPointerToMember leaveScope VALUE_ID_REF endPointerToMember
  6229. {
  6230. $$.setExpr(parser->createIndirectSelect($1.getExpr(), $4.getExpr(), $1), $1);
  6231. }
  6232. ;
  6233. optMaxMin
  6234. : { $$.setNullExpr(); }
  6235. | ',' MAX {
  6236. $$.setExpr(createAttribute(maxAtom));
  6237. $$.setPosition($1);
  6238. }
  6239. | ',' MIN {
  6240. $$.setExpr(createAttribute(minAtom));
  6241. $$.setPosition($1);
  6242. }
  6243. ;
  6244. beginCounterScope
  6245. :
  6246. {
  6247. parser->counterStack.append(* new OwnedHqlExprItem);
  6248. $$.clear();
  6249. }
  6250. ;
  6251. endCounterScope
  6252. : {
  6253. $$.setNullExpr();
  6254. if (parser->counterStack.ordinality())
  6255. {
  6256. $$.setExpr(parser->counterStack.tos().value.getClear());
  6257. parser->counterStack.pop();
  6258. }
  6259. }
  6260. ;
  6261. optAscDesc
  6262. : { $$.setNullExpr(); }
  6263. | ',' DESC { $$.setExpr(createAttribute(descAtom)); }
  6264. ;
  6265. optExtraFilter
  6266. : { $$.setNullExpr(); }
  6267. | ',' booleanExpr { $$.setExpr($2.getExpr()); }
  6268. ;
  6269. regexOpt
  6270. : { $$.setNullExpr(); }
  6271. | ',' NOCASE { $$.setExpr(createAttribute(noCaseAtom)); }
  6272. ;
  6273. xmlEncodeFlags
  6274. : { $$.setNullExpr(); }
  6275. | ',' ALL { $$.setExpr(createAttribute(allAtom)); }
  6276. ;
  6277. aggregateFlags
  6278. : { $$.setNullExpr(); }
  6279. | ',' KEYED { $$.setExpr(createAttribute(keyedAtom)); $$.setPosition($2); }
  6280. | ',' prefetchAttribute
  6281. {
  6282. $$.setExpr($2.getExpr(), $2);
  6283. }
  6284. ;
  6285. transfer
  6286. : TYPE_LPAREN typeDef TYPE_RPAREN
  6287. { $$ = $2; }
  6288. ;
  6289. atomicValue
  6290. : qualifiedFieldName
  6291. | const { $$.setExpr($1.getExpr()); }
  6292. ;
  6293. moduleScopeDot
  6294. : abstractModule '.'
  6295. {
  6296. OwnedHqlExpr expr = $1.getExpr();
  6297. parser->modScope.set(expr->queryScope());
  6298. $$.setExpr(parser->checkConcreteModule($1, expr));
  6299. $$.setPosition($1);
  6300. }
  6301. | pseudoResolutionScope '.'
  6302. {
  6303. $$.setExpr(createNullScope());
  6304. }
  6305. ;
  6306. pseudoResolutionScope
  6307. : '^' {
  6308. parser->outerScopeAccessDepth = 1;
  6309. $$.clear();
  6310. }
  6311. | pseudoResolutionScope '^'
  6312. {
  6313. ++parser->outerScopeAccessDepth;
  6314. $$.clear();
  6315. }
  6316. ;
  6317. abstractModule
  6318. : SCOPE_ID {
  6319. IHqlExpression *expr = $1.getExpr();
  6320. $$.setExpr(expr);
  6321. }
  6322. | moduleScopeDot SCOPE_ID leaveScope
  6323. {
  6324. $1.release();
  6325. IHqlExpression *expr = $2.getExpr();
  6326. $$.setExpr(expr, $2);
  6327. }
  6328. | '$'
  6329. {
  6330. IHqlExpression * scopeExpr = queryExpression(parser->globalScope);
  6331. $$.setExpr(LINK(scopeExpr), $1);
  6332. }
  6333. | VALUE_MACRO abstractModule ENDMACRO
  6334. {
  6335. $$.setExpr($2.getExpr());
  6336. }
  6337. | moduleScopeDot VALUE_MACRO leaveScope abstractModule ENDMACRO
  6338. {
  6339. $1.release();
  6340. $$.setExpr($4.getExpr(), $4);
  6341. }
  6342. | scopeFunctionWithParameters
  6343. {
  6344. OwnedHqlExpr value = $1.getExpr();
  6345. IHqlExpression * func;
  6346. IHqlExpression * params = NULL;
  6347. if (value->getOperator() == no_comma)
  6348. {
  6349. func = value->queryChild(0);
  6350. params = value->queryChild(1);
  6351. }
  6352. else
  6353. func = value;
  6354. IHqlExpression * expr = parser->bindParameters($1, func, params);
  6355. $$.setExpr(expr, $1);
  6356. }
  6357. | STORED '(' abstractModule ')'
  6358. {
  6359. OwnedHqlExpr scope = $3.getExpr();
  6360. OwnedHqlExpr storedScope = parser->createStoredModule($3, scope);
  6361. $$.setExpr(storedScope.getClear());
  6362. $$.setPosition($1);
  6363. }
  6364. | compoundModule
  6365. | LIBRARY '(' libraryName ',' scopeFunction ','
  6366. {
  6367. parser->beginFunctionCall($5);
  6368. }
  6369. actualParameters ')'
  6370. {
  6371. //Need to create a library definition from referenced attribute, adding the name/internal attribute
  6372. //and then bind it to create the library instance.
  6373. OwnedHqlExpr name = $3.getExpr();
  6374. OwnedHqlExpr func = $5.getExpr();
  6375. HqlExprArray actuals;
  6376. $8.unwindCommaList(actuals);
  6377. $$.setExpr(parser->createLibraryInstance($1, name, func, actuals));
  6378. $$.setPosition($1);
  6379. }
  6380. | LIBRARY '(' libraryName ',' scopeFunctionWithParameters ')'
  6381. {
  6382. OwnedHqlExpr value = $5.getExpr();
  6383. IHqlExpression * func;
  6384. HqlExprArray actuals;
  6385. if (value->getOperator() == no_comma)
  6386. {
  6387. func = value->queryChild(0);
  6388. value->queryChild(1)->unwindList(actuals, no_comma);
  6389. }
  6390. else
  6391. func = value;
  6392. //Need to create a library definition from referenced attribute, adding the name/internal attribute
  6393. //and then bind it to create the library instance.
  6394. OwnedHqlExpr name = $3.getExpr();
  6395. $$.setExpr(parser->createLibraryInstance($1, name, func, actuals));
  6396. $$.setPosition($1);
  6397. }
  6398. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN abstractModule ';' endInlineFunctionToken
  6399. {
  6400. Owned<ITypeInfo> retType = $1.getType();
  6401. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  6402. }
  6403. | IF '(' booleanExpr ',' abstractModule ',' abstractModule ')'
  6404. {
  6405. OwnedHqlExpr trueExpr = $5.getExpr();
  6406. OwnedITypeInfo scopeType = trueExpr->getType(); // actually needs to be the common base class.
  6407. OwnedHqlExpr module = createValue(no_if, scopeType.getClear(), $3.getExpr(), LINK(trueExpr), $7.getExpr());
  6408. $$.setExpr(createDelayedScope(module.getClear()), $1);
  6409. }
  6410. ;
  6411. scopeFunctionWithParameters
  6412. : scopeFunction '('
  6413. {
  6414. parser->beginFunctionCall($1);
  6415. }
  6416. actualParameters ')'
  6417. {
  6418. //Slightly ugly that we need this production to common up the code
  6419. //but otherwise we get s/r errors
  6420. OwnedHqlExpr parms = $4.getExpr();
  6421. //NB: Do not call createComma() incase the first argument is a dataset
  6422. if (parms)
  6423. $$.setExpr(createValue(no_comma, $1.getExpr(), parms.getClear()), $1);
  6424. else
  6425. $$.setExpr($1.getExpr(), $1);
  6426. }
  6427. ;
  6428. libraryName
  6429. : expression
  6430. {
  6431. parser->normalizeExpression($1, type_string, false);
  6432. //default name of library implementation name
  6433. $$.setExpr(createExprAttribute(nameAtom, $1.getExpr()));
  6434. }
  6435. | INTERNAL '(' scopeFunction ')'
  6436. {
  6437. //want to create a name based on the name of the scope reference, but one that will be commmoned up between all
  6438. //internal instances of the same library.
  6439. OwnedHqlExpr internal = $3.getExpr();
  6440. IAtom * name = internal->queryName();
  6441. StringBuffer nameText;
  6442. nameText.append("lib").append(name).append("_").append(getExpressionCRC(internal));
  6443. OwnedHqlExpr nameExpr = createExprAttribute(nameAtom, createConstant(nameText.str()));
  6444. $$.setExpr(createComma(nameExpr.getClear(), createExprAttribute(internalAtom, internal.getClear()), createAttribute(_original_Atom, createAttribute(name))));
  6445. }
  6446. ;
  6447. leaveScope
  6448. : {
  6449. parser->dotScope.clear();
  6450. parser->modScope.clear();
  6451. parser->outerScopeAccessDepth = 0;
  6452. $$.clear();
  6453. }
  6454. ;
  6455. scopeProjectOpts
  6456. : { $$.setNullExpr(); }
  6457. | scopeProjectOpts ',' scopeProjectOpt
  6458. {
  6459. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  6460. $$.setPosition($2);
  6461. }
  6462. ;
  6463. scopeProjectOpt
  6464. : OPT { $$.setExpr(createAttribute(optAtom)); $$.setPosition($1); }
  6465. | UNKNOWN_ID // Will include known ids as well since they won't be returned as known ids.
  6466. {
  6467. $$.setExpr(createId($1.getId()));
  6468. $$.setPosition($1);
  6469. }
  6470. ;
  6471. qualifiedFieldName
  6472. : dotScope VALUE_ID leaveScope
  6473. {
  6474. IHqlExpression *e1 = $1.getExpr();
  6475. IHqlExpression *e3 = $2.getExpr();
  6476. assertex(e1 && e1->getOperator() != no_record);
  6477. if (e3->getOperator() == no_field)
  6478. $$.setExpr(parser->createSelect(e1, e3, $2), $1);
  6479. else
  6480. {
  6481. e1->Release(); // some error occurred elsewhere
  6482. $$.setExpr(e3, $1);
  6483. }
  6484. }
  6485. | dotScope startPointerToMember leaveScope VALUE_ID_REF endPointerToMember
  6486. {
  6487. IHqlExpression *e1 = $1.getExpr();
  6488. IHqlExpression *e3 = $4.getExpr();
  6489. $$.setExpr(parser->createIndirectSelect(e1, e3, $4), $1);
  6490. }
  6491. | globalValueAttribute
  6492. ;
  6493. globalValueAttribute
  6494. : VALUE_ID
  6495. | startPointerToMember VALUE_ID_REF endPointerToMember
  6496. {
  6497. //This means look id up in the current top scope. It doesn't make sense if there is no active dataset
  6498. OwnedHqlExpr rhs = $2.getExpr();
  6499. IHqlExpression *top = parser->queryTopScope();
  6500. if (top && top->queryRecord())
  6501. {
  6502. $$.setExpr(parser->createIndirectSelect(LINK(top), rhs.getClear(), $1));
  6503. }
  6504. else
  6505. {
  6506. IIdAtom * name = parser->createFieldNameFromExpr(rhs);
  6507. const char * text = name ? name->str() : "?";
  6508. parser->reportError(ERR_OBJ_NOACTIVEDATASET, $1, "No active dataset to resolve field '%s'", text);
  6509. $$.setExpr(createNullExpr(rhs));
  6510. }
  6511. }
  6512. | moduleScopeDot VALUE_ID leaveScope
  6513. {
  6514. $1.release();
  6515. $$.setExpr($2.getExpr(), $1);
  6516. }
  6517. | VALUE_MACRO expression ENDMACRO
  6518. {
  6519. $$.setExpr($2.getExpr(), $1);
  6520. }
  6521. | moduleScopeDot VALUE_MACRO leaveScope expression ENDMACRO
  6522. {
  6523. $1.release();
  6524. $$.setExpr($4.getExpr(), $1);
  6525. }
  6526. | valueFunction '('
  6527. {
  6528. parser->beginFunctionCall($1);
  6529. }
  6530. actualParameters ')'
  6531. {
  6532. $$.setExpr(parser->bindParameters($1, $4.getExpr()));
  6533. }
  6534. ;
  6535. dataRow
  6536. : dataSet '[' expression ']'
  6537. {
  6538. parser->normalizeExpression($3, type_int, false);
  6539. $$.setExpr(createRow(no_selectnth, $1.getExpr(), $3.getExpr()));
  6540. }
  6541. | dictionary '[' expressionList ']'
  6542. {
  6543. HqlExprArray args;
  6544. $3.unwindCommaList(args);
  6545. OwnedHqlExpr dict = $1.getExpr();
  6546. OwnedHqlExpr row = createValue(no_rowvalue, makeNullType(), args);
  6547. $$.setExpr(createSelectMapRow(*parser->errorHandler, $3.pos, dict, row));
  6548. }
  6549. | dataSet '[' NOBOUNDCHECK expression ']'
  6550. {
  6551. parser->normalizeExpression($4, type_int, false);
  6552. $$.setExpr(createRow(no_selectnth, $1.getExpr(), createComma($4.getExpr(), createAttribute(noBoundCheckAtom))));
  6553. }
  6554. | dotScope DATAROW_ID leaveScope
  6555. {
  6556. IHqlExpression *e1 = $1.getExpr();
  6557. IHqlExpression *e2 = $2.getExpr();
  6558. $$.setExpr(parser->createSelect(e1, e2, $2));
  6559. }
  6560. | dotScope RECORD_ID leaveScope
  6561. {
  6562. IHqlExpression *e1 = $1.getExpr();
  6563. IHqlExpression *e2 = $2.getExpr();
  6564. $$.setExpr(parser->createSelect(e1, e2, $2));
  6565. }
  6566. | moduleScopeDot DATAROW_ID leaveScope
  6567. {
  6568. $1.release();
  6569. $$.setExpr($2.getExpr());
  6570. }
  6571. | datarowFunction '('
  6572. {
  6573. parser->beginFunctionCall($1);
  6574. }
  6575. actualParameters ')'
  6576. {
  6577. $$.setExpr(parser->bindParameters($1, $4.getExpr()));
  6578. }
  6579. | simpleDataRow
  6580. | VALUE_MACRO dataRow ENDMACRO
  6581. {
  6582. $$.setExpr($2.getExpr());
  6583. $$.setPosition($1);
  6584. }
  6585. | moduleScopeDot VALUE_MACRO leaveScope dataRow ENDMACRO
  6586. {
  6587. $1.release();
  6588. $$.setExpr($4.getExpr());
  6589. $$.setPosition($2);
  6590. }
  6591. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN dataRow ';' endInlineFunctionToken
  6592. {
  6593. Owned<ITypeInfo> retType = $1.getType();
  6594. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  6595. }
  6596. ;
  6597. simpleDataRow
  6598. : DATAROW_ID
  6599. | LEFT {
  6600. $$.setExpr(parser->getSelector($1, no_left), $1);
  6601. }
  6602. | RIGHT {
  6603. $$.setExpr(parser->getSelector($1, no_right), $1);
  6604. }
  6605. | RIGHT_NN
  6606. {
  6607. //Slightly bizarre syntax - really only here for the merge transform of a user defined aggregate
  6608. IHqlExpression *right = parser->queryRightScope();
  6609. if (right)
  6610. {
  6611. OwnedHqlExpr selSeq = parser->getSelectorSequence();
  6612. OwnedHqlExpr selector = createSelector(no_right, right, selSeq);
  6613. OwnedHqlExpr rows = parser->resolveRows($1, selector);
  6614. OwnedHqlExpr index = createConstant(createIntValue($1.getInt(), LINK(parser->defaultIntegralType)));
  6615. $$.setExpr(createRow(no_selectnth, rows.getClear(), index.getClear()), $1);
  6616. }
  6617. else
  6618. {
  6619. parser->reportError(ERR_RIGHT_ILL_HERE, $1, "RIGHT not legal here");
  6620. $$.setExpr(createRow(no_null, LINK(queryNullRecord())), $1);
  6621. }
  6622. }
  6623. | IF '(' booleanExpr ',' dataRow ',' dataRow ')'
  6624. {
  6625. $$.setExpr(parser->processIfProduction($3, $5, &$7), $1);
  6626. }
  6627. | IF '(' booleanExpr ',' dataRow ')'
  6628. {
  6629. $$.setExpr(parser->processIfProduction($3, $5, NULL), $1);
  6630. }
  6631. | IFF '(' booleanExpr ',' dataRow ',' dataRow ')'
  6632. {
  6633. parser->ensureDataset($5);
  6634. parser->ensureDataset($7);
  6635. OwnedHqlExpr ds = parser->processIfProduction($3, $5, &$7);
  6636. $$.setExpr(createRow(no_selectnth, ds.getClear(), getSizetConstant(1)), $1);
  6637. }
  6638. | IFF '(' booleanExpr ',' dataRow ')'
  6639. {
  6640. parser->ensureDataset($5);
  6641. OwnedHqlExpr ds = parser->processIfProduction($3, $5, NULL);
  6642. $$.setExpr(createRow(no_selectnth, ds.getClear(), getSizetConstant(1)), $1);
  6643. }
  6644. | HTTPCALL '(' expression ',' expression ',' expression ',' recordDef ')'
  6645. {
  6646. parser->normalizeExpression($3);
  6647. parser->normalizeExpression($5);
  6648. parser->normalizeExpression($7);
  6649. IHqlExpression * ds = createDataset(no_httpcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr()));
  6650. $$.setExpr(createRow(no_selectnth, ds, createConstantOne()));
  6651. }
  6652. | HTTPCALL '(' expression ',' expression ',' expression ',' recordDef ',' soapFlags ')'
  6653. {
  6654. parser->normalizeExpression($3);
  6655. parser->normalizeExpression($5);
  6656. parser->normalizeExpression($7);
  6657. IHqlExpression * ds = createDataset(no_httpcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr()));
  6658. $$.setExpr(createRow(no_selectnth, ds, createConstantOne()));
  6659. }
  6660. | SOAPCALL '(' expression ',' expression ',' recordDef ',' recordDef ')'
  6661. {
  6662. parser->normalizeExpression($3);
  6663. parser->checkSoapRecord($7);
  6664. IHqlExpression * ds = createDataset(no_soapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr()));
  6665. $$.setExpr(createRow(no_selectnth, ds, createConstantOne()));
  6666. }
  6667. | SOAPCALL '(' expression ',' expression ',' recordDef ',' recordDef ',' soapFlags ')'
  6668. {
  6669. parser->normalizeExpression($3);
  6670. parser->normalizeExpression($5);
  6671. parser->checkSoapRecord($7);
  6672. IHqlExpression * ds = createDataset(no_soapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr()));
  6673. $$.setExpr(createRow(no_selectnth, ds, createConstantOne()));
  6674. parser->checkOnFailRecord($$.queryExpr(), $1);
  6675. }
  6676. | SOAPCALL '(' expression ',' expression ',' recordDef ',' transform ',' recordDef ')'
  6677. {
  6678. parser->normalizeExpression($3);
  6679. parser->normalizeExpression($5);
  6680. IHqlExpression * ds = createDataset(no_newsoapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr()));
  6681. $$.setExpr(createRow(no_selectnth, ds, createConstantOne()));
  6682. }
  6683. | SOAPCALL '(' expression ',' expression ',' recordDef ',' transform ',' recordDef ',' soapFlags ')'
  6684. {
  6685. parser->normalizeExpression($3);
  6686. parser->normalizeExpression($5);
  6687. IHqlExpression * ds = createDataset(no_newsoapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), createComma($9.getExpr(), $11.getExpr(), $13.getExpr())));
  6688. $$.setExpr(createRow(no_selectnth, ds, createConstantOne()));
  6689. parser->checkOnFailRecord($$.queryExpr(), $1);
  6690. }
  6691. | ROW '(' inlineDatasetValue ',' recordDef ')'
  6692. {
  6693. OwnedHqlExpr row = createRow(no_temprow, $3.getExpr(), $5.getExpr());
  6694. $$.setExpr(convertTempRowToCreateRow(*parser->errorHandler, $3.pos, row));
  6695. $$.setPosition($1);
  6696. }
  6697. | ROW '(' startLeftSeqRow ',' recordDef ')' endSelectorSequence
  6698. {
  6699. OwnedHqlExpr row = $3.getExpr();
  6700. OwnedHqlExpr record = $5.getExpr();
  6701. $7.release();
  6702. OwnedHqlExpr transform = parser->createDefaultAssignTransform(record, row, $5);
  6703. $$.setExpr(createRow(no_createrow, transform.getClear()), $1);
  6704. }
  6705. | ROW '(' startLeftSeqRow ',' transform ')' endSelectorSequence
  6706. {
  6707. $$.setExpr(parser->createProjectRow($3, $5, $7), $1);
  6708. }
  6709. | ROW '(' transform ')'
  6710. {
  6711. OwnedHqlExpr transform = $3.getExpr();
  6712. $$.setExpr(createRow(no_createrow, transform.getClear()));
  6713. $$.setPosition($1);
  6714. }
  6715. | ROW '(' simpleRecord ')'
  6716. {
  6717. parser->checkSoapRecord($3);
  6718. OwnedHqlExpr record = $3.getExpr();
  6719. $$.setExpr(createRow(no_createrow, convertRecordToTransform(record, false)));
  6720. $$.setPosition($1);
  6721. }
  6722. | ROW '(' dataSet ')'
  6723. {
  6724. OwnedHqlExpr ds = $3.getExpr();
  6725. $$.setExpr(ensureActiveRow(ds));
  6726. $$.setPosition($1);
  6727. }
  6728. | ROW '(' '[' ']' ',' simpleRecord ')'
  6729. {
  6730. OwnedHqlExpr record = $6.getExpr();
  6731. OwnedHqlExpr transform = parser->createClearTransform(record, $7);
  6732. $$.setExpr(createRow(no_createrow, LINK(transform)));
  6733. $$.setPosition($1);
  6734. }
  6735. | PROJECT '(' startLeftSeqRow ',' transform ')' endSelectorSequence
  6736. {
  6737. $$.setExpr(parser->createProjectRow($3, $5, $7), $1);
  6738. }
  6739. | GLOBAL '(' dataRow globalOpts ')'
  6740. {
  6741. $$.setExpr(createRow(no_globalscope, $3.getExpr(), $4.getExpr()));
  6742. $$.setPosition($1);
  6743. }
  6744. | GLOBAL '(' dataRow ',' expression globalOpts ')'
  6745. {
  6746. parser->normalizeExpression($5, type_string, false);
  6747. $$.setExpr(createRow(no_globalscope, $3.getExpr(), createComma($5.getExpr(), $6.getExpr())));
  6748. $$.setPosition($1);
  6749. }
  6750. | NOFOLD '(' dataRow ')'
  6751. {
  6752. $$.setExpr(createRow(no_nofold, $3.getExpr(), NULL));
  6753. $$.setPosition($1);
  6754. }
  6755. | NOHOIST '(' dataRow ')'
  6756. {
  6757. $$.setExpr(createRow(no_nohoist, $3.getExpr(), NULL));
  6758. $$.setPosition($1);
  6759. }
  6760. | LOCAL '(' dataRow ')'
  6761. {
  6762. $$.setExpr(createRow(no_forcelocal, $3.getExpr()));
  6763. $$.setPosition($1);
  6764. }
  6765. | NOLOCAL '(' dataRow ')'
  6766. {
  6767. $$.setExpr(createRow(no_forcenolocal, $3.getExpr()));
  6768. $$.setPosition($1);
  6769. }
  6770. | ALLNODES '(' beginList dataRow ignoreDummyList ')'
  6771. {
  6772. $$.setExpr(createRow(no_allnodes, $4.getExpr()));
  6773. $$.setPosition($1);
  6774. }
  6775. | THISNODE '(' dataRow ')'
  6776. {
  6777. $$.setExpr(createRow(no_thisnode, $3.getExpr()));
  6778. $$.setPosition($1);
  6779. }
  6780. | TRANSFER '(' expression ',' recordDef ')'
  6781. {
  6782. parser->normalizeExpression($3);
  6783. IHqlExpression *expr = $3.getExpr();
  6784. IHqlExpression *record = $5.getExpr();
  6785. // if ((exprType->getSize() != UNKNOWN_LENGTH) && (exprType->getSize() < type->getSize()) && type->getSize() != UNKNOWN_LENGTH)
  6786. // parser->reportError(ERR_TYPETRANS_LARGERTYPE, $5, "Type transfer: target type in is larger than source type");
  6787. $$.setExpr(createRow(no_typetransfer, record, expr));
  6788. $$.setPosition($1);
  6789. }
  6790. | __COMMON__ '(' dataRow ')'
  6791. {
  6792. $$.setExpr(createAliasOwn($3.getExpr(), NULL));
  6793. $$.setPosition($1);
  6794. }
  6795. | SKIP '(' ROW recordDef ')'
  6796. {
  6797. if (!parser->curTransform)
  6798. parser->reportError(ERR_PARSER_CANNOTRECOVER,$1,"SKIP is only valid inside a TRANSFORM");
  6799. $$.setExpr(createRow(no_skip, $4.getExpr()));
  6800. }
  6801. | MATCHROW '(' patternReference ')'
  6802. {
  6803. IHqlExpression * record = $3.queryExpr()->queryRecord();
  6804. if (!record)
  6805. {
  6806. parser->reportError(ERR_NOT_ROW_RULE,$1,"Referenced rule does not have a associated row");
  6807. record = queryNullRecord();
  6808. }
  6809. $$.setExpr(createRow(no_matchrow, LINK(record), $3.getExpr())); //, parser->createUniqueId())));
  6810. }
  6811. | FROMXML '(' recordDef ',' expression optCommaTrim ')'
  6812. {
  6813. parser->normalizeExpression($5, type_stringorunicode, false);
  6814. $$.setExpr(createRow(no_fromxml, $3.getExpr(), createComma($5.getExpr(), $6.getExpr())), $1);
  6815. }
  6816. | WHEN '(' dataRow ',' action ')'
  6817. {
  6818. $$.setExpr(createCompound($5.getExpr(), $3.getExpr()), $1);
  6819. }
  6820. ;
  6821. dictionary
  6822. : simpleDictionary
  6823. | dictionary '+' dictionary
  6824. { parser->createAppendDictionaries($$, $1, $3, NULL); }
  6825. ;
  6826. simpleDictionary
  6827. : scopedDictionaryId
  6828. | NOFOLD '(' dictionary ')'
  6829. {
  6830. $$.setExpr(createDictionary(no_nofold, $3.getExpr(), NULL));
  6831. $$.setPosition($1);
  6832. }
  6833. | NOHOIST '(' dictionary ')'
  6834. {
  6835. $$.setExpr(createDictionary(no_nohoist, $3.getExpr(), NULL));
  6836. $$.setPosition($1);
  6837. }
  6838. | THISNODE '(' dictionary ')'
  6839. {
  6840. $$.setExpr(createDictionary(no_thisnode, $3.getExpr()), $1);
  6841. }
  6842. | DICTIONARY '(' startTopFilter ',' recordDef ')' endTopFilter
  6843. {
  6844. OwnedHqlExpr dataset = $3.getExpr();
  6845. parser->checkOutputRecord($5, false);
  6846. OwnedHqlExpr record = $5.getExpr();
  6847. HqlExprArray args;
  6848. args.append(*LINK(dataset));
  6849. args.append(*LINK(record));
  6850. OwnedHqlExpr ds = createDataset(no_usertable, args);
  6851. parser->checkProjectedFields(ds, $5);
  6852. $$.setExpr(createDictionary(no_createdictionary, ds.getClear()), $1);
  6853. }
  6854. | DICTIONARY '(' startTopFilter ')' endTopFilter
  6855. {
  6856. OwnedHqlExpr ds = $3.getExpr();
  6857. $$.setExpr(createDictionary(no_createdictionary, ds.getClear()), $1);
  6858. }
  6859. | DICTIONARY '(' '[' ']' ',' recordDef ')'
  6860. {
  6861. HqlExprArray values; // Empty list
  6862. OwnedHqlExpr table = createDataset(no_temptable, createValue(no_recordlist, NULL, values), $6.getExpr());
  6863. OwnedHqlExpr ds = convertTempTableToInlineTable(*parser->errorHandler, $4.pos, table);
  6864. $$.setExpr(createDictionary(no_createdictionary, ds.getClear()), $1);
  6865. }
  6866. | DICTIONARY '(' '[' beginList inlineDatasetValueList ']' ',' recordDef ')'
  6867. {
  6868. HqlExprArray values;
  6869. parser->endList(values);
  6870. OwnedHqlExpr table = createDataset(no_temptable, createValue(no_recordlist, NULL, values), $8.getExpr());
  6871. OwnedHqlExpr ds = convertTempTableToInlineTable(*parser->errorHandler, $5.pos, table);
  6872. $$.setExpr(createDictionary(no_createdictionary, ds.getClear()), $1);
  6873. }
  6874. | '(' dictionary ')' {
  6875. $$.setExpr($2.getExpr());
  6876. $$.setPosition($1);
  6877. }
  6878. | IF '(' booleanExpr ',' dictionary ',' dictionary ')'
  6879. {
  6880. OwnedHqlExpr ds = parser->processIfProduction($3, $5, &$7);
  6881. $$.setExpr(ds.getClear(), $1);
  6882. }
  6883. | IF '(' booleanExpr ',' dictionary ')'
  6884. {
  6885. OwnedHqlExpr ds = parser->processIfProduction($3, $5, NULL);
  6886. $$.setExpr(ds.getClear(), $1);
  6887. }
  6888. | IFF '(' booleanExpr ',' dictionary ',' dictionary ')'
  6889. {
  6890. OwnedHqlExpr ds = parser->processIfProduction($3, $5, &$7);
  6891. $$.setExpr(ds.getClear(), $1);
  6892. }
  6893. | IFF '(' booleanExpr ',' dictionary ')'
  6894. {
  6895. OwnedHqlExpr ds = parser->processIfProduction($3, $5, NULL);
  6896. $$.setExpr(ds.getClear(), $1);
  6897. }
  6898. | MAP '(' mapDictionarySpec ',' dictionary ')'
  6899. {
  6900. HqlExprArray args;
  6901. IHqlExpression * elseDict = $5.getExpr();
  6902. $3.unwindCommaList(args);
  6903. ForEachItemIn(idx, args)
  6904. {
  6905. IHqlExpression * cur = args.item(idx).queryChild(1);
  6906. parser->checkRecordTypesMatch(cur, elseDict, $5);
  6907. }
  6908. args.append(*elseDict);
  6909. $$.setExpr(::createDictionary(no_map, args));
  6910. $$.setPosition($1);
  6911. }
  6912. | MAP '(' mapDictionarySpec ')'
  6913. {
  6914. HqlExprArray args;
  6915. $3.unwindCommaList(args);
  6916. IHqlExpression * elseDict;
  6917. if (args.ordinality())
  6918. elseDict = createNullExpr(&args.item(0));
  6919. else
  6920. elseDict = createDictionary(no_null, LINK(queryNullRecord()));
  6921. ForEachItemIn(idx, args)
  6922. {
  6923. IHqlExpression * cur = args.item(idx).queryChild(1);
  6924. parser->checkRecordTypesMatch(cur, elseDict, $1);
  6925. }
  6926. args.append(*elseDict);
  6927. $$.setExpr(::createDictionary(no_map, args));
  6928. $$.setPosition($1);
  6929. }
  6930. | CASE '(' expression ',' beginList caseDictionarySpec ',' dictionary ')'
  6931. {
  6932. parser->normalizeExpression($3, type_scalar, false);
  6933. HqlExprArray args;
  6934. IHqlExpression * elseDict = $8.getExpr();
  6935. parser->endList(args);
  6936. parser->checkCaseForDuplicates(args, $6);
  6937. ForEachItemIn(idx, args)
  6938. {
  6939. IHqlExpression * cur = args.item(idx).queryChild(1);
  6940. parser->checkRecordTypesMatch(cur, elseDict, $8);
  6941. }
  6942. args.add(*$3.getExpr(),0);
  6943. args.append(*elseDict);
  6944. $$.setExpr(::createDataset(no_case, args));
  6945. $$.setPosition($1);
  6946. }
  6947. | CASE '(' expression ',' beginList caseDictionarySpec ')'
  6948. {
  6949. parser->normalizeExpression($3, type_scalar, false);
  6950. HqlExprArray args;
  6951. parser->endList(args);
  6952. IHqlExpression * elseDict;
  6953. if (args.ordinality())
  6954. elseDict = createNullExpr(&args.item(0));
  6955. else
  6956. elseDict = createDictionary(no_null, LINK(queryNullRecord()));
  6957. parser->checkCaseForDuplicates(args, $6);
  6958. ForEachItemIn(idx, args)
  6959. {
  6960. IHqlExpression * cur = args.item(idx).queryChild(1);
  6961. parser->checkRecordTypesMatch(cur, elseDict, $6);
  6962. }
  6963. args.add(*$3.getExpr(),0);
  6964. args.append(*elseDict);
  6965. $$.setExpr(::createDictionary(no_case, args));
  6966. $$.setPosition($1);
  6967. }
  6968. | CASE '(' expression ',' beginList dictionary ')'
  6969. {
  6970. parser->normalizeExpression($3, type_scalar, false);
  6971. // change error to warning.
  6972. parser->reportWarning(WRN_CASENOCONDITION, $1.pos, "CASE does not have any conditions");
  6973. HqlExprArray list;
  6974. parser->endList(list);
  6975. $3.release();
  6976. $$.setExpr($6.getExpr(), $1);
  6977. }
  6978. | FAIL '(' dictionary failDatasetParam ')'
  6979. {
  6980. OwnedHqlExpr dict = $3.getExpr();
  6981. //Actually allow a sequence of arbitrary actions....
  6982. $$.setExpr(createDictionary(no_fail, LINK(dict->queryRecord()), $4.getExpr()));
  6983. $$.setPosition($1);
  6984. }
  6985. | TOK_ERROR '(' dictionary failDatasetParam ')'
  6986. {
  6987. OwnedHqlExpr dict = $3.getExpr();
  6988. //Actually allow a sequence of arbitrary actions....
  6989. $$.setExpr(createDictionary(no_fail, LINK(dict->queryRecord()), $4.getExpr()));
  6990. $$.setPosition($1);
  6991. }
  6992. | CHOOSE '(' expression ',' dictionaryList ')'
  6993. {
  6994. parser->normalizeExpression($3, type_int, false);
  6995. OwnedHqlExpr values = $5.getExpr();
  6996. HqlExprArray args;
  6997. values->unwindList(args, no_comma);
  6998. IHqlExpression * compareDict = NULL;
  6999. ForEachItemIn(idx, args)
  7000. {
  7001. IHqlExpression * cur = &args.item(idx);
  7002. if (cur->queryRecord())
  7003. {
  7004. if (compareDict)
  7005. {
  7006. parser->checkRecordTypesMatch(cur, compareDict, $5);
  7007. }
  7008. else
  7009. compareDict = cur;
  7010. }
  7011. }
  7012. args.add(*$3.getExpr(), 0);
  7013. $$.setExpr(createDictionary(no_chooseds, args), $1); // no_choosedict ?
  7014. }
  7015. ;
  7016. dictionaryList
  7017. : dictionary
  7018. | dictionary ',' dictionaryList
  7019. {
  7020. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  7021. $$.setPosition($1);
  7022. }
  7023. ;
  7024. scopedDictionaryId
  7025. : globalScopedDictionaryId
  7026. | dotScope DICTIONARY_ID leaveScope
  7027. {
  7028. IHqlExpression *e1 = $1.getExpr();
  7029. IHqlExpression *e2 = $2.getExpr();
  7030. if (e1 && (e1->getOperator() != no_record) && (e2->getOperator() == no_field))
  7031. $$.setExpr(parser->createSelect(e1, e2, $2));
  7032. else
  7033. {
  7034. ::Release(e1);
  7035. $$.setExpr(e2);
  7036. }
  7037. }
  7038. | dictionaryFunction '('
  7039. {
  7040. parser->beginFunctionCall($1);
  7041. }
  7042. actualParameters ')'
  7043. {
  7044. $$.setExpr(parser->bindParameters($1, $4.getExpr()));
  7045. }
  7046. ;
  7047. globalScopedDictionaryId
  7048. : DICTIONARY_ID
  7049. | moduleScopeDot DICTIONARY_ID leaveScope
  7050. {
  7051. OwnedHqlExpr scope = $1.getExpr();
  7052. $$.setExpr($2.getExpr());
  7053. }
  7054. ;
  7055. dataSet
  7056. : simpleDataSet
  7057. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN dataSet ';' endInlineFunctionToken
  7058. {
  7059. Owned<ITypeInfo> retType = $1.getType();
  7060. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  7061. }
  7062. | startSimpleFilter conditions endSimpleFilter /* simple dataset with conditions */
  7063. {
  7064. IHqlExpression *filter = $2.getExpr();
  7065. IHqlExpression *dataset = $1.getExpr();
  7066. $$.setExpr(filter ? createDataset(no_filter, dataset, filter) : dataset, $1);
  7067. }
  7068. | dataRow conditions
  7069. {
  7070. /** Error production **/
  7071. parser->reportError(ERR_EXPECTED_DATASET, $1, "Expected a dataset instead of a row");
  7072. $2.release();
  7073. $$.setExpr(createDatasetFromRow($1.getExpr()), $1);
  7074. }
  7075. | VALUE_MACRO dataSet ENDMACRO { $$.setExpr($2.getExpr()); }
  7076. | moduleScopeDot VALUE_MACRO leaveScope dataSet ENDMACRO
  7077. {
  7078. $1.release();
  7079. $$.setExpr($4.getExpr());
  7080. }
  7081. | dataSet '-' dataSet
  7082. {
  7083. OwnedHqlExpr left = $1.getExpr();
  7084. OwnedHqlExpr right = $3.getExpr();
  7085. parser->checkRecordTypesSimilar(left, right, $3);
  7086. OwnedHqlExpr seq = parser->createActiveSelectorSequence(left, right);
  7087. OwnedHqlExpr leftSelect = createSelector(no_left, left, seq);
  7088. OwnedHqlExpr rightSelect = createSelector(no_right, right, seq);
  7089. OwnedHqlExpr transform = parser->createDefaultAssignTransform(left->queryRecord(), leftSelect, $1);
  7090. OwnedHqlExpr cond = createBoolExpr(no_eq, LINK(leftSelect), LINK(rightSelect));
  7091. $$.setExpr(createDatasetF(no_join, LINK(left), LINK(right), cond.getClear(), transform.getClear(), LINK(seq), createAttribute(leftonlyAtom), NULL), $1);
  7092. }
  7093. /*
  7094. The following would implement (X - Y) + (Y - X), but it would need a new operator since ^ is overloaded for the scope resolution
  7095. | dataSet '^' dataSet
  7096. {
  7097. OwnedHqlExpr left = $1.getExpr();
  7098. OwnedHqlExpr right = $3.getExpr();
  7099. parser->checkRecordTypesSimilar(left, right, $3);
  7100. OwnedHqlExpr seq = parser->createActiveSelectorSequence(left, right);
  7101. OwnedHqlExpr leftSelect = createSelector(no_left, left, seq);
  7102. OwnedHqlExpr rightSelect = createSelector(no_right, right, seq);
  7103. OwnedHqlExpr transform = parser->createDefaultAssignTransform(left->queryRecord(), leftSelect, $1);
  7104. OwnedHqlExpr cond = createBoolExpr(no_eq, LINK(leftSelect), LINK(rightSelect));
  7105. $$.setExpr(createDatasetF(no_join, LINK(left), LINK(right), cond.getClear(), transform.getClear(), LINK(seq), createAttribute(fullonlyAtom), NULL), $1);
  7106. }
  7107. */
  7108. | dataSet '+' dataSet
  7109. { parser->createAppendFiles($$, $1, $3, NULL); }
  7110. | dataSet '&' dataSet
  7111. { parser->createAppendFiles($$, $1, $3, _ordered_Atom); }
  7112. | dataSet ANDAND dataSet
  7113. { parser->createAppendFiles($$, $1, $3, _orderedPull_Atom); }
  7114. | dataSet '+' dataRow
  7115. { parser->createAppendFiles($$, $1, $3, NULL); }
  7116. | dataSet '&' dataRow
  7117. { parser->createAppendFiles($$, $1, $3, _ordered_Atom); }
  7118. | dataSet ANDAND dataRow
  7119. { parser->createAppendFiles($$, $1, $3, _orderedPull_Atom); }
  7120. | dataRow '+' dataSet
  7121. { parser->createAppendFiles($$, $1, $3, NULL); }
  7122. | dataRow '&' dataSet
  7123. { parser->createAppendFiles($$, $1, $3, _ordered_Atom); }
  7124. | dataRow ANDAND dataSet
  7125. { parser->createAppendFiles($$, $1, $3, _orderedPull_Atom); }
  7126. | dataRow '+' dataRow
  7127. { parser->createAppendFiles($$, $1, $3, NULL); }
  7128. | dataRow '&' dataRow
  7129. { parser->createAppendFiles($$, $1, $3, _ordered_Atom); }
  7130. | dataRow ANDAND dataRow
  7131. { parser->createAppendFiles($$, $1, $3, _orderedPull_Atom); }
  7132. | dataSet '[' expression DOTDOT expression ']'
  7133. {
  7134. parser->normalizeExpression($3, type_int, false);
  7135. parser->normalizeExpression($5, type_int, false);
  7136. parser->applyDefaultPromotions($3, true);
  7137. parser->applyDefaultPromotions($5, true);
  7138. Owned<ITypeInfo> type = parser->promoteToSameType($3, $5);
  7139. IHqlExpression * ds = $1.getExpr();
  7140. IHqlExpression * from = $3.getExpr();
  7141. IHqlExpression * to = $5.getExpr();
  7142. IHqlExpression * length = createValue(no_add, LINK(type), createValue(no_sub, LINK(type), to, LINK(from)), createConstant(type->castFrom(true, (__int64)1)));
  7143. $$.setExpr(createDataset(no_choosen, ds, createComma(length, from)));
  7144. }
  7145. | dataSet '[' DOTDOT expression ']'
  7146. {
  7147. parser->normalizeExpression($4, type_int, false);
  7148. IHqlExpression * ds = $1.getExpr();
  7149. IHqlExpression * length = $4.getExpr();
  7150. $$.setExpr(createDataset(no_choosen, ds, length));
  7151. }
  7152. | dataSet '[' expression DOTDOT ']'
  7153. {
  7154. parser->normalizeExpression($3, type_int, false);
  7155. IHqlExpression * ds = $1.getExpr();
  7156. IHqlExpression * from = $3.getExpr();
  7157. $$.setExpr(createDataset(no_choosen, ds, createComma(createConstant(CHOOSEN_ALL_LIMIT), from)));
  7158. }
  7159. ;
  7160. simpleDataSet
  7161. : scopedDatasetId
  7162. | setOfDatasets '[' expression ']'
  7163. {
  7164. parser->normalizeExpression($3, type_int, false);
  7165. $$.setExpr(createDataset(no_rowsetindex, $1.getExpr(), $3.getExpr()));
  7166. $$.setPosition($1);
  7167. }
  7168. | ALIAS '(' dataSet ')'
  7169. {
  7170. $$.setExpr(createDataset(no_dataset_alias, $3.getExpr(), ::createUniqueId()), $1);
  7171. }
  7172. | EBCDIC '(' startTopFilter ')' endTopFilter
  7173. {
  7174. IHqlExpression *ds = $3.getExpr();
  7175. OwnedHqlExpr ebcdicRecord = parser->transformRecord(ds, ebcdicAtom, $3);
  7176. if (ebcdicRecord)
  7177. {
  7178. OwnedHqlExpr seq = parser->createActiveSelectorSequence(ds, NULL);
  7179. OwnedHqlExpr left = createSelector(no_left, ds, seq);
  7180. OwnedHqlExpr transform = parser->createDefaultAssignTransform(ebcdicRecord, left, $1);
  7181. $$.setExpr(createDatasetF(no_transformebcdic, ds, transform.getClear(), LINK(seq), NULL));
  7182. }
  7183. else
  7184. $$.setExpr(ds);
  7185. $$.setPosition($1);
  7186. }
  7187. | ASCII '(' startTopFilter ')' endTopFilter
  7188. {
  7189. IHqlExpression *ds = $3.getExpr();
  7190. OwnedHqlExpr asciiRecord = parser->transformRecord(ds, asciiAtom, $3);
  7191. if (asciiRecord)
  7192. {
  7193. OwnedHqlExpr seq = parser->createActiveSelectorSequence(ds, NULL);
  7194. OwnedHqlExpr left = createSelector(no_left, ds, seq);
  7195. OwnedHqlExpr transform = parser->createDefaultAssignTransform(asciiRecord, left, $1);
  7196. $$.setExpr(createDatasetF(no_transformascii, ds, transform.getClear(), LINK(seq), NULL));
  7197. }
  7198. else
  7199. $$.setExpr(ds);
  7200. $$.setPosition($1);
  7201. }
  7202. | CHOOSEN '(' dataSet ',' expression choosenExtra ')'
  7203. {
  7204. if ($5.queryExpr()->getOperator() == no_all)
  7205. $5.release().setExpr(createConstant(CHOOSEN_ALL_LIMIT));
  7206. parser->normalizeExpression($5, type_int, false);
  7207. IHqlExpression * limit = $5.getExpr();
  7208. if (limit->queryValue() && limit->queryValue()->getIntValue() == 0)
  7209. parser->reportWarning(WRN_CHOOSEN_ALL,$1.pos,"Use CHOOSEN(dataset, ALL) to remove implicit choosen. CHOOSEN(dataset, 0) now returns no records.");
  7210. $$.setExpr(createDataset(no_choosen, $3.getExpr(), createComma(limit, $6.getExpr())), $1);
  7211. parser->attachPendingWarnings($$);
  7212. }
  7213. | CHOOSESETS '(' startTopFilter ',' setCountList ')' endTopFilter
  7214. {
  7215. $$.setExpr(createDataset(no_choosesets, $3.getExpr(), $5.getExpr()));
  7216. $$.setPosition($1);
  7217. }
  7218. | DEDUP '(' startTopLeftRightSeqFilter optDedupFlags ')' endTopLeftRightFilter endSelectorSequence
  7219. {
  7220. IHqlExpression *ds = $3.getExpr();
  7221. parser->expandWholeAndExcept(ds, $4);
  7222. IHqlExpression *flags = $4.getExpr();
  7223. //checkDedup(ds, flags, $3);
  7224. OwnedHqlExpr dedup = createDataset(no_dedup, ds, createComma(flags, $7.getExpr()));
  7225. parser->checkDistribution($3, dedup, false);
  7226. bool hasHash = dedup->hasAttribute(hashAtom);
  7227. if (hasHash || dedup->hasAttribute(allAtom))
  7228. {
  7229. IHqlExpression * keep = dedup->queryAttribute(keepAtom);
  7230. if (keep && !matchesConstantValue(keep->queryChild(0), 1))
  7231. parser->reportError(ERR_DEDUP_ALL_KEEP, $4, "KEEP is not supported for DEDUP(ALL)");
  7232. }
  7233. if (hasHash)
  7234. {
  7235. if (dedup->hasAttribute(rightAtom))
  7236. parser->reportError(ERR_DEDUP_ALL_KEEP, $4, "RIGHT is not supported for DEDUP(HASH)");
  7237. }
  7238. $$.setExpr(dedup.getClear(), $1);
  7239. }
  7240. | DISTRIBUTE '(' startTopFilter startDistributeAttrs ',' expression optDistributeAttrs ')' endTopFilter
  7241. {
  7242. parser->normalizeExpression($6, type_numeric, false);
  7243. $$.setExpr(createDataset(no_distribute, $3.getExpr(), createComma($6.getExpr(), $7.getExpr())));
  7244. $$.setPosition($1);
  7245. }
  7246. | DISTRIBUTE '(' startTopFilter startDistributeAttrs optDistributeAttrs ')' endTopFilter
  7247. {
  7248. OwnedHqlExpr ds = $3.getExpr();
  7249. OwnedHqlExpr active = ensureActiveRow(ds);
  7250. //Expand row components (see parser->processSortList() for similar code for hash)
  7251. HqlExprArray components;
  7252. RecordSelectIterator iter(active->queryRecord(), active);
  7253. ForEach(iter)
  7254. components.append(*iter.get());
  7255. OwnedHqlExpr sortlist = createSortList(components);
  7256. OwnedHqlExpr hash = createValue(no_hash32, makeIntType(4, false), LINK(sortlist), createAttribute(internalAtom));
  7257. $$.setExpr(createDataset(no_distribute, ds.getClear(), createComma(hash.getClear(), $5.getExpr())), $1);
  7258. }
  7259. | DISTRIBUTE '(' startTopFilter startDistributeAttrs ',' skewAttribute optDistributeAttrs ')' endTopFilter
  7260. {
  7261. $$.setExpr(createDataset(no_distribute, $3.getExpr(), createComma($6.getExpr(), $7.getExpr())));
  7262. $$.setPosition($1);
  7263. }
  7264. | DISTRIBUTE '(' startTopFilter startDistributeAttrs ',' PARTITION_ATTR '(' beginList sortList ')' optDistributeAttrs ')' endTopFilter
  7265. {
  7266. HqlExprArray sortItems;
  7267. parser->endList(sortItems);
  7268. OwnedHqlExpr fields = parser->processSortList($9, no_distribute, NULL, sortItems, NULL, NULL);
  7269. HqlExprArray args;
  7270. unwindChildren(args, fields);
  7271. OwnedHqlExpr value = createValue(no_sortpartition, LINK(parser->defaultIntegralType), args);
  7272. $$.setExpr(createDatasetF(no_distribute, $3.getExpr(), value.getClear(), $11.getExpr(), NULL));
  7273. $$.setPosition($1);
  7274. }
  7275. | DISTRIBUTE '(' startTopFilter startDistributeAttrs ',' startRightDistributeSeqFilter endTopFilter ',' expression optKeyedDistributeAttrs ')' endSelectorSequence
  7276. {
  7277. parser->normalizeExpression($9, type_boolean, false);
  7278. IHqlExpression * left = $3.getExpr();
  7279. IHqlExpression * right = $6.getExpr();
  7280. IHqlExpression * cond = $9.getExpr();
  7281. OwnedHqlExpr attr = $10.getExpr();
  7282. if (!isKey(right))
  7283. parser->reportError(ERR_EXPECTED_INDEX,$5,"Expected an index as the second parameter");
  7284. IHqlExpression * ds = createDataset(no_keyeddistribute, left, createComma(right, cond, LINK(attr), $12.getExpr()));
  7285. JoinSortInfo joinInfo;
  7286. joinInfo.findJoinSortOrders(cond, NULL, NULL, NULL, false);
  7287. unsigned numUnsortedFields = numPayloadFields(right);
  7288. if (joinInfo.extraMatch || (!ds->hasAttribute(firstAtom) && (joinInfo.queryLeftReq().ordinality() != getFieldCount(right->queryRecord())-numUnsortedFields)))
  7289. parser->reportError(ERR_MATCH_KEY_EXACTLY,$9,"Condition on DISTRIBUTE must match the key exactly");
  7290. if (joinInfo.hasOptionalEqualities())
  7291. parser->reportError(ERR_MATCH_KEY_EXACTLY,$9,"field[1..*] is not supported for a keyed distribute");
  7292. //Should check that all index fields are accounted for...
  7293. $$.setExpr(ds);
  7294. $$.setPosition($1);
  7295. }
  7296. | DISTRIBUTE '(' startTopFilter startDistributeAttrs ',' startRightDistributeSeqFilter endTopFilter optKeyedDistributeAttrs ')' endSelectorSequence
  7297. {
  7298. IHqlExpression * left = $3.getExpr();
  7299. IHqlExpression * right = $6.getExpr();
  7300. if (!isKey(right))
  7301. parser->reportError(ERR_EXPECTED_INDEX,$6,"Expected an index as the second parameter");
  7302. IHqlExpression * cond = parser->createDistributeCond(left, right, $6, $10);
  7303. IHqlExpression * ds = createDataset(no_keyeddistribute, left, createComma(right, cond, $8.getExpr(), $10.getExpr()));
  7304. //Should check that all index fields are accounted for...
  7305. $$.setExpr(ds);
  7306. $$.setPosition($1);
  7307. }
  7308. | DISTRIBUTED '(' startTopFilter ',' expression distributedFlags ')' endTopFilter
  7309. {
  7310. parser->normalizeExpression($5, type_numeric, false);
  7311. $$.setExpr(createDataset(no_distributed, $3.getExpr(), createComma($5.getExpr(), $6.getExpr())));
  7312. $$.setPosition($1);
  7313. }
  7314. | DISTRIBUTED '(' startTopFilter ')' endTopFilter
  7315. {
  7316. $$.setExpr(createDataset(no_distributed, $3.getExpr(), createAttribute(unknownAtom)));
  7317. $$.setPosition($1);
  7318. }
  7319. | PARTITION '(' startTopFilter ',' startSortOrder beginList sortList ')' endSortOrder endTopFilter
  7320. {
  7321. HqlExprArray sortItems;
  7322. parser->endList(sortItems);
  7323. OwnedHqlExpr fields = parser->processSortList($7, no_distribute, NULL, sortItems, NULL, NULL);
  7324. HqlExprArray args;
  7325. unwindChildren(args, fields);
  7326. OwnedHqlExpr value = createValue(no_sortpartition, LINK(parser->defaultIntegralType), args);
  7327. $$.setExpr(createDataset(no_distribute, $3.getExpr(), value.getClear()));
  7328. $$.setPosition($1);
  7329. }
  7330. | JOIN '(' startLeftDelaySeqFilter ',' startRightFilter ',' expression opt_join_transform_flags ')' endSelectorSequence
  7331. {
  7332. parser->normalizeExpression($7, type_boolean, false);
  7333. IHqlExpression * left = $3.getExpr();
  7334. IHqlExpression * right = $5.getExpr();
  7335. IHqlExpression * cond = $7.getExpr();
  7336. OwnedHqlExpr flags = $8.getExpr();
  7337. OwnedHqlExpr transform;
  7338. if (flags)
  7339. {
  7340. if (flags->getOperator() == no_comma)
  7341. {
  7342. IHqlExpression * child0 = flags->queryChild(0);
  7343. if (child0->isTransform())
  7344. {
  7345. transform.set(child0);
  7346. flags.set(flags->queryChild(1));
  7347. }
  7348. }
  7349. else if (flags->isTransform())
  7350. transform.setown(flags.getClear());
  7351. }
  7352. if (!transform)
  7353. {
  7354. IHqlExpression * seq = $10.queryExpr();
  7355. transform.setown(parser->createDefJoinTransform(left,right,$1,seq,flags));
  7356. }
  7357. IHqlExpression *join = createDataset(no_join, left, createComma(right, cond, createComma(transform.getClear(), flags.getClear(), $10.getExpr())));
  7358. bool isLocal = join->hasAttribute(localAtom);
  7359. parser->checkDistribution($3, left, isLocal, true);
  7360. parser->checkDistribution($5, right, isLocal, true);
  7361. parser->checkJoinFlags($1, join);
  7362. parser->checkOnFailRecord(join, $1);
  7363. if (!join->hasAttribute(allAtom))
  7364. parser->warnIfFoldsToConstant(cond, $7);
  7365. $$.setExpr(join, $1);
  7366. }
  7367. | MERGEJOIN '(' startTopLeftRightSeqSetDatasets ',' startLeftRows expression ',' endRowsGroup beginList sortList ')' endTopLeftRightFilter endSelectorSequence
  7368. {
  7369. HqlExprArray sortItems;
  7370. parser->endList(sortItems);
  7371. parser->normalizeExpression($6, type_boolean, false);
  7372. IHqlExpression * ds = $3.getExpr();
  7373. IHqlExpression * cond = $6.getExpr();
  7374. OwnedHqlExpr flags;
  7375. parser->expandSortedAsList(sortItems);
  7376. IHqlExpression * order = parser->processSortList($10, no_mergejoin, ds, sortItems, NULL, &flags);
  7377. IHqlExpression * join = createDataset(no_mergejoin, ds, createComma(cond, order, flags.getClear(), createComma($8.getExpr(), $13.getExpr())));
  7378. $$.setExpr(join);
  7379. $$.setPosition($1);
  7380. }
  7381. | JOIN '(' startTopLeftRightSeqSetDatasets ',' startLeftRows expression ',' transform ',' mergeJoinFlags ')' endRowsGroup endTopLeftRightFilter endSelectorSequence
  7382. {
  7383. parser->normalizeExpression($6, type_boolean, false);
  7384. IHqlExpression * ds = $3.getExpr();
  7385. IHqlExpression * cond = $6.getExpr();
  7386. IHqlExpression * tform = $8.getExpr();
  7387. if (!queryAttributeInList(sortedAtom, $10.queryExpr()))
  7388. parser->reportError(ERR_EXPECTED, $10, "SORTED() is required for STEPPED join");
  7389. OwnedHqlExpr flags;
  7390. HqlExprArray sortItems;
  7391. $10.unwindCommaList(sortItems);
  7392. parser->expandSortedAsList(sortItems);
  7393. IHqlExpression * order = parser->processSortList($10, no_nwayjoin, ds, sortItems, NULL, &flags);
  7394. IHqlExpression * join = createDataset(no_nwayjoin, ds, createComma(cond, tform, order, createComma(flags.getClear(), $12.getExpr(), $14.getExpr())));
  7395. $$.setExpr(join);
  7396. $$.setPosition($1);
  7397. }
  7398. | MERGE '(' startTopLeftRightSeqSetDatasets ',' beginList sortList ')' endTopLeftRightFilter endSelectorSequence
  7399. {
  7400. HqlExprArray sortItems;
  7401. parser->endList(sortItems);
  7402. if (!queryAttribute(sortedAtom, sortItems))
  7403. parser->reportWarning(WRN_MERGE_RECOMMEND_SORTED, $1.pos, "MERGE without an explicit SORTED() attribute is deprecated");
  7404. IHqlExpression * ds = $3.getExpr();
  7405. parser->expandSortedAsList(sortItems);
  7406. OwnedHqlExpr flags;
  7407. IHqlExpression * order = parser->processSortList($6, no_nwaymerge, ds, sortItems, NULL, &flags);
  7408. IHqlExpression * join = createDataset(no_nwaymerge, ds, createComma(order, flags.getClear(), $9.getExpr()));
  7409. $$.setExpr(join, $1);
  7410. parser->attachPendingWarnings($$);
  7411. }
  7412. | PROCESS '(' startLeftDelaySeqFilter ',' startRightRow ',' beginCounterScope transform ',' transform optCommonAttrs ')' endCounterScope endSelectorSequence
  7413. {
  7414. IHqlExpression * left = $3.getExpr();
  7415. IHqlExpression * right = $5.getExpr();
  7416. IHqlExpression * counter = $13.getExpr();
  7417. IHqlExpression * attr = $11.getExpr();
  7418. if (counter)
  7419. attr = createComma(attr, createAttribute(_countProject_Atom, counter));
  7420. parser->ensureTransformTypeMatch($8, left);
  7421. parser->ensureTransformTypeMatch($10, right);
  7422. $$.setExpr(createDataset(no_process, left, createComma(right, $8.getExpr(), $10.getExpr(), createComma(attr, $14.getExpr()))));
  7423. $$.setPosition($1);
  7424. }
  7425. | ROLLUP '(' startTopLeftRightSeqFilter ',' expression ',' transform optCommonAttrs ')' endTopLeftRightFilter endSelectorSequence
  7426. {
  7427. parser->normalizeExpression($5);
  7428. parser->ensureTransformTypeMatch($7, $3.queryExpr());
  7429. OwnedHqlExpr tr = $7.getExpr();
  7430. IHqlExpression *attr = $8.getExpr();
  7431. $$.setExpr(createDataset(no_rollup, $3.getExpr(), createComma($5.getExpr(), tr.getClear(), attr, $11.getExpr())));
  7432. parser->checkDistribution($3, $$.queryExpr(), false);
  7433. $$.setPosition($1);
  7434. }
  7435. | ROLLUP '(' startTopLeftRightSeqFilter ',' transform rollupExtra ')' endTopLeftRightFilter endSelectorSequence
  7436. {
  7437. IHqlExpression *ds = $3.getExpr();
  7438. IHqlExpression *tr = $5.getExpr();
  7439. OwnedHqlExpr seq = $9.getExpr();
  7440. parser->expandWholeAndExcept(ds, $6);
  7441. OwnedHqlExpr extra = $6.getExpr();
  7442. HqlExprArray args;
  7443. if (extra)
  7444. extra->unwindList(args, no_comma);
  7445. IHqlExpression * attr = NULL;
  7446. IHqlExpression * cond = NULL;
  7447. OwnedHqlExpr left = createSelector(no_left, ds, seq);
  7448. OwnedHqlExpr right = createSelector(no_right, ds, seq);
  7449. HqlExprArray values;
  7450. ForEachItemIn(idx, args)
  7451. {
  7452. IHqlExpression & cur = args.item(idx);
  7453. if (cur.isAttribute())
  7454. attr = createComma(attr, LINK(&cur));
  7455. else
  7456. values.append(OLINK(cur));
  7457. }
  7458. if (values.ordinality())
  7459. cond = createSortList(values);
  7460. else
  7461. cond = createConstant(true);
  7462. if (!recordTypesMatch(ds, tr))
  7463. parser->reportError(ERR_TRANSFORM_TYPE_MISMATCH,$5,"Type returned from transform must match the source dataset type");
  7464. $$.setExpr(createDataset(no_rollup, ds, createComma(cond, tr, attr, LINK(seq))));
  7465. parser->checkDistribution($3, $$.queryExpr(), false);
  7466. $$.setPosition($1);
  7467. }
  7468. | ROLLUP '(' startTopLeftRightSeqFilter ',' startLeftRowsGroup ',' transform ')' endRowsGroup endTopLeftRightFilter endSelectorSequence
  7469. {
  7470. parser->checkGrouped($3);
  7471. IHqlExpression *attr = NULL;
  7472. $$.setExpr(createDataset(no_rollupgroup, $3.getExpr(), createComma($7.getExpr(), attr, $9.getExpr(), $11.getExpr())));
  7473. $$.setPosition($1);
  7474. }
  7475. | COMBINE '(' startLeftDelaySeqFilter ',' startRightFilter ')' endSelectorSequence
  7476. {
  7477. IHqlExpression * left = $3.getExpr();
  7478. IHqlExpression * right = $5.getExpr();
  7479. IHqlExpression * transform = parser->createDefJoinTransform(parser->queryLeftScope(),parser->queryRightScope(),$1, $7.queryExpr(),NULL);
  7480. IHqlExpression * combine = createDataset(no_combine, left, createComma(right, transform, $7.getExpr()));
  7481. $$.setExpr(combine);
  7482. $$.setPosition($1);
  7483. }
  7484. | COMBINE '(' startLeftDelaySeqFilter ',' startRightFilter ',' transform optCommonAttrs ')' endSelectorSequence
  7485. {
  7486. IHqlExpression * left = $3.getExpr();
  7487. IHqlExpression * right = $5.getExpr();
  7488. IHqlExpression * combine = createDataset(no_combine, left, createComma(right, $7.getExpr(), $8.getExpr(), $10.getExpr()));
  7489. $$.setExpr(combine);
  7490. $$.setPosition($1);
  7491. }
  7492. | COMBINE '(' startLeftDelaySeqFilter ',' startRightFilter ',' startRightRowsGroup ',' transform optCommonAttrs ')' endRowsGroup endSelectorSequence
  7493. {
  7494. IHqlExpression * left = $3.getExpr();
  7495. IHqlExpression * right = $5.getExpr();
  7496. IHqlExpression * combine = createDataset(no_combinegroup, left, createComma(right, $9.getExpr(), $10.getExpr(), createComma($12.getExpr(), $13.getExpr())));
  7497. $$.setExpr(combine);
  7498. $$.setPosition($1);
  7499. }
  7500. | LOOP '(' startLeftRowsSeqFilter beginCounterScope ',' expression ',' dataSet endCounterScope loopOptions ')' endRowsGroup endSelectorSequence
  7501. {
  7502. parser->normalizeExpression($6);
  7503. parser->ensureDatasetTypeMatch($8, $3.queryExpr());
  7504. parser->checkBooleanOrNumeric($6);
  7505. IHqlExpression * left = $3.getExpr();
  7506. IHqlExpression * body = createValue(no_loopbody, makeNullType(), $8.getExpr());
  7507. IHqlExpression * counter = $9.getExpr();
  7508. if (counter)
  7509. body = createComma(body, createAttribute(_countProject_Atom, counter));
  7510. IHqlExpression * loopCondition = parser->createLoopCondition(left, $6.getExpr(), NULL, $13.queryExpr(), $12.queryExpr());
  7511. IHqlExpression * loopExpr = createDataset(no_loop, left, createComma(loopCondition, body, $10.getExpr(), createComma($12.getExpr(), $13.getExpr())));
  7512. parser->checkLoopFlags($1, loopExpr);
  7513. $$.setExpr(loopExpr);
  7514. $$.setPosition($1);
  7515. }
  7516. | LOOP '(' startLeftRowsSeqFilter beginCounterScope ',' expression ',' expression ',' dataSet endCounterScope loopOptions ')' endRowsGroup endSelectorSequence
  7517. {
  7518. parser->ensureDatasetTypeMatch($10, $3.queryExpr());
  7519. parser->normalizeExpression($6);
  7520. parser->checkBooleanOrNumeric($6);
  7521. parser->normalizeExpression($8, type_boolean, false);
  7522. IHqlExpression * left = $3.getExpr();
  7523. IHqlExpression * body = createValue(no_loopbody, makeNullType(), $10.getExpr());
  7524. IHqlExpression * counter = $11.getExpr();
  7525. if (counter)
  7526. body = createComma(body, createAttribute(_countProject_Atom, counter));
  7527. IHqlExpression * loopCondition = parser->createLoopCondition(left, $6.getExpr(), $8.getExpr(), $15.queryExpr(), $14.queryExpr());
  7528. IHqlExpression * loopExpr = createDataset(no_loop, left, createComma(loopCondition, body, $12.getExpr(), createComma($14.getExpr(), $15.getExpr())));
  7529. parser->checkLoopFlags($1, loopExpr);
  7530. $$.setExpr(loopExpr);
  7531. $$.setPosition($1);
  7532. }
  7533. | LOOP '(' startLeftRowsSeqFilter beginCounterScope ',' expression ',' expression ',' expression ',' dataSet endCounterScope loopOptions ')' endRowsGroup endSelectorSequence
  7534. {
  7535. //LOOP(ds, <count>,<filter-cond>,<loop-cond>, f(rows(left)))
  7536. parser->ensureDatasetTypeMatch($12, $3.queryExpr());
  7537. parser->normalizeExpression($6, type_numeric, false);
  7538. parser->normalizeExpression($8, type_boolean, false);
  7539. parser->normalizeExpression($10, type_boolean, false);
  7540. IHqlExpression * left = $3.getExpr();
  7541. IHqlExpression * body = createValue(no_loopbody, makeNullType(), $12.getExpr());
  7542. IHqlExpression * counter = $13.getExpr();
  7543. if (counter)
  7544. body = createComma(body, createAttribute(_countProject_Atom, counter));
  7545. IHqlExpression * loopCondition = createComma($6.getExpr(), $8.getExpr(), $10.getExpr());
  7546. IHqlExpression * loopExpr = createDataset(no_loop, left, createComma(loopCondition, body, $14.getExpr(), createComma($16.getExpr(), $17.getExpr())));
  7547. parser->checkLoopFlags($1, loopExpr);
  7548. $$.setExpr(loopExpr);
  7549. $$.setPosition($1);
  7550. }
  7551. | GRAPH '(' startLeftRowsSeqFilter beginCounterScope ',' expression ',' dataSet endCounterScope graphOptions ')' endRowsGroup endSelectorSequence
  7552. {
  7553. parser->ensureDatasetTypeMatch($8, $3.queryExpr());
  7554. parser->normalizeExpression($6);
  7555. parser->checkBooleanOrNumeric($6);
  7556. IHqlExpression * left = $3.getExpr();
  7557. IHqlExpression * body = createValue(no_loopbody, makeNullType(), $8.getExpr());
  7558. IHqlExpression * counter = $9.getExpr();
  7559. if (counter)
  7560. body = createComma(body, createAttribute(_countProject_Atom, counter));
  7561. IHqlExpression * loopExpr = createDataset(no_graphloop, left, createComma($6.getExpr(), body, $10.getExpr(), createComma($12.getExpr(), $13.getExpr())));
  7562. parser->checkLoopFlags($1, loopExpr);
  7563. $$.setExpr(loopExpr);
  7564. $$.setPosition($1);
  7565. }
  7566. | GRAPH '(' startLeftRowsSeqFilter ')' endRowsGroup endSelectorSequence
  7567. {
  7568. $5.release();
  7569. $6.release();
  7570. $$.setExpr(createDataset(no_forcegraph, $3.getExpr()), $1);
  7571. }
  7572. | ITERATE '(' startLeftRightSeqFilter ',' beginCounterScope transform optCommonAttrs ')' endCounterScope endSelectorSequence
  7573. {
  7574. parser->ensureTransformTypeMatch($6, $3.queryExpr());
  7575. IHqlExpression *ds = $3.getExpr();
  7576. IHqlExpression *tr = $6.getExpr();
  7577. IHqlExpression *attr = $7.getExpr();
  7578. IHqlExpression * counter = $9.getExpr();
  7579. if (counter)
  7580. attr = createComma(attr, createAttribute(_countProject_Atom, counter));
  7581. $$.setExpr(createDataset(no_iterate, ds, createComma(tr, attr, $10.getExpr())));
  7582. $$.setPosition($1);
  7583. parser->checkDistribution($3, $$.queryExpr(), false);
  7584. }
  7585. | LIMIT '(' dataSet ',' expression limitOptions ')'
  7586. {
  7587. parser->normalizeExpression($5, type_int, false);
  7588. OwnedHqlExpr ds = $3.getExpr();
  7589. HqlExprArray args;
  7590. args.append(*LINK(ds));
  7591. args.append(*$5.getExpr());
  7592. $6.unwindCommaList(args);
  7593. node_operator op = queryAttribute(keyedAtom, args) || queryAttribute(countAtom, args) ? no_keyedlimit : no_limit;
  7594. IHqlExpression * onFail = queryAttribute(onFailAtom, args);
  7595. if (onFail && !parser->checkTransformTypeMatch($6, ds, onFail->queryChild(0)))
  7596. args.zap(*onFail);
  7597. $$.setExpr(createDataset(op, args));
  7598. $$.setPosition($1);
  7599. }
  7600. | TOK_CATCH '(' dataSet ',' catchOption optCommonAttrs ')'
  7601. {
  7602. OwnedHqlExpr ds = $3.getExpr();
  7603. HqlExprArray args;
  7604. args.append(*LINK(ds));
  7605. args.append(*$5.getExpr());
  7606. $6.unwindCommaList(args);
  7607. IHqlExpression * onFail = queryAttribute(onFailAtom, args);
  7608. if (onFail && !parser->checkTransformTypeMatch($4, ds, onFail->queryChild(0)))
  7609. args.zap(*onFail);
  7610. $$.setExpr(createDataset(no_catchds, args));
  7611. $$.setPosition($1);
  7612. }
  7613. /*
  7614. | TOK_CATCH '(' dataSet ',' expression ',' catchOption optCommonAttrs ')'
  7615. {
  7616. parser->normalizeExpression($5, type_boolean, false);
  7617. OwnedHqlExpr ds = $3.getExpr();
  7618. HqlExprArray args;
  7619. args.append(*LINK(ds));
  7620. args.append(*$5.getExpr());
  7621. args.append(*$7.getExpr());
  7622. $8.unwindCommaList(args);
  7623. IHqlExpression * onFail = queryAttribute(onFailAtom, args);
  7624. if (onFail && !parser->checkTransformTypeMatch($4, ds, onFail->queryChild(0)))
  7625. args.zap(*onFail);
  7626. $$.setExpr(createDataset(no_catchds, args));
  7627. $$.setPosition($1);
  7628. }
  7629. */
  7630. | MERGE '(' startTopFilter ',' mergeDataSetList ')' endTopFilter
  7631. {
  7632. bool isLocal = queryAttributeInList(localAtom, $5.queryExpr()) != NULL;
  7633. parser->checkMergeInputSorted($3, isLocal);
  7634. OwnedHqlExpr ds = $3.getExpr();
  7635. HqlExprArray args, orderedArgs;
  7636. args.append(*LINK(ds));
  7637. OwnedHqlExpr rest=$5.getExpr();
  7638. if (rest)
  7639. rest->unwindList(args, no_comma);
  7640. IHqlExpression * sorted = queryAttribute(sortedAtom, args);
  7641. OwnedHqlExpr newSorted;
  7642. if (!sorted)
  7643. {
  7644. parser->reportWarning(WRN_MERGE_RECOMMEND_SORTED, $1.pos, "MERGE without an explicit SORTED() attribute is deprecated");
  7645. OwnedHqlExpr order = getExistingSortOrder(ds, isLocal, true);
  7646. HqlExprArray sorts;
  7647. if (order)
  7648. unwindChildren(sorts, order);
  7649. newSorted.setown(createExprAttribute(sortedAtom, sorts));
  7650. args.append(*LINK(newSorted));
  7651. // because parameters aren't substituted, need to deduce the sort order again later once they are
  7652. args.append(*createAttribute(_implicitSorted_Atom));
  7653. }
  7654. else
  7655. {
  7656. newSorted.setown(replaceSelector(sorted, ds->queryNormalizedSelector(), queryActiveTableSelector()));
  7657. args.zap(*sorted);
  7658. args.append(*LINK(newSorted));
  7659. }
  7660. ForEachItemIn(i, args)
  7661. {
  7662. IHqlExpression & cur = args.item(i);
  7663. if (cur.isDataset())
  7664. parser->checkMergeSortOrder($1, ds, &cur, newSorted);
  7665. }
  7666. reorderAttributesToEnd(orderedArgs, args);
  7667. IHqlExpression *merge = createDataset(no_merge, orderedArgs);
  7668. $$.setExpr(merge);
  7669. $$.setPosition($1);
  7670. }
  7671. | COGROUP '(' startTopFilter ',' cogroupDataSetList ')' endTopFilter
  7672. {
  7673. OwnedHqlExpr ds = $3.getExpr();
  7674. OwnedHqlExpr rest=$5.getExpr();
  7675. HqlExprArray args;
  7676. args.append(*LINK(ds));
  7677. if (rest)
  7678. rest->unwindList(args, no_comma);
  7679. IHqlExpression * group = queryAttribute(groupAtom, args);
  7680. if (!group)
  7681. {
  7682. parser->reportError(ERR_COGROUP_NO_GROUP, $1, "COGROUP requires a GROUP() parameter");
  7683. args.append(*createExprAttribute(groupAtom, getUnknownSortlist()));
  7684. }
  7685. else
  7686. {
  7687. OwnedHqlExpr newGroup = replaceSelector(group, ds->queryNormalizedSelector(), queryActiveTableSelector());
  7688. args.zap(*group);
  7689. args.append(*newGroup.getClear());
  7690. }
  7691. parser->checkRecordsMatch($3, args);
  7692. HqlExprArray orderedArgs;
  7693. reorderAttributesToEnd(orderedArgs, args);
  7694. $$.setExpr(createDataset(no_cogroup, orderedArgs), $1);
  7695. }
  7696. | NONEMPTY '(' mergeDataSetList ')' // mergeDataSetList to allow ,LOCAL
  7697. {
  7698. HqlExprArray args, orderedArgs;
  7699. $3.unwindCommaList(args);
  7700. parser->checkRecordsMatch($3, args);
  7701. reorderAttributesToEnd(orderedArgs, args);
  7702. $$.setExpr(createDataset(no_nonempty, args));
  7703. $$.setPosition($1);
  7704. }
  7705. | PROJECT '(' startLeftSeqFilter ',' beginCounterScope transform endCounterScope projectOptions ')' endSelectorSequence
  7706. {
  7707. IHqlExpression *te = createComma($6.getExpr(), $8.getExpr(), $10.getExpr());
  7708. IHqlExpression *ds = $3.getExpr();
  7709. OwnedHqlExpr counter = $7.getExpr();
  7710. if (counter)
  7711. te = createComma(te, createAttribute(_countProject_Atom, LINK(counter)));
  7712. $$.setExpr(createDataset(no_hqlproject, ds, te));
  7713. $$.setPosition($1);
  7714. }
  7715. | PROJECT '(' startLeftSeqFilter ',' beginCounterScope recordDef endCounterScope projectOptions ')' endSelectorSequence
  7716. {
  7717. OwnedHqlExpr transform = parser->createRowAssignTransform($3, $6, $10);
  7718. $6.release();
  7719. $7.release();
  7720. $$.setExpr(createDataset(no_hqlproject, $3.getExpr(), createComma(transform.getClear(), $8.getExpr(), $10.getExpr())));
  7721. $$.setPosition($1);
  7722. }
  7723. | PULL '(' startTopFilter ')' endTopFilter
  7724. {
  7725. $$.setExpr(createDataset(no_metaactivity, $3.getExpr(), createAttribute(pullAtom)));
  7726. $$.setPosition($1);
  7727. }
  7728. | DENORMALIZE '(' startLeftDelaySeqFilter ',' startRightFilter ',' expression ',' beginCounterScope transform endCounterScope optJoinFlags ')' endSelectorSequence
  7729. {
  7730. parser->normalizeExpression($7, type_boolean, false);
  7731. IHqlExpression * ds = $3.getExpr();
  7732. parser->ensureTransformTypeMatch($10, ds);
  7733. IHqlExpression * transform = $10.getExpr();
  7734. IHqlExpression * counter = $11.getExpr();
  7735. if (counter)
  7736. counter = createAttribute(_countProject_Atom, counter);
  7737. //MORE: This should require local otherwise it needs to do a full join type thing.
  7738. IHqlExpression * extra = createComma($5.getExpr(), $7.getExpr(), transform, createComma($12.getExpr(), counter, $14.getExpr()));
  7739. $$.setExpr(createDataset(no_denormalize, ds, extra));
  7740. $$.setPosition($1);
  7741. parser->checkJoinFlags($1, $$.queryExpr());
  7742. }
  7743. | DENORMALIZE '(' startLeftDelaySeqFilter ',' startRightFilter ',' expression ',' beginCounterScope startRightRowsGroup endCounterScope ',' transform optJoinFlags ')' endRowsGroup endSelectorSequence
  7744. {
  7745. parser->normalizeExpression($7, type_boolean, false);
  7746. IHqlExpression * ds = $3.getExpr();
  7747. IHqlExpression * transform = $13.getExpr();
  7748. IHqlExpression * extra = createComma($5.getExpr(), $7.getExpr(), transform, createComma($14.getExpr(), $16.getExpr(), $17.getExpr()));
  7749. $$.setExpr(createDataset(no_denormalizegroup, ds, extra));
  7750. $$.setPosition($1);
  7751. $11.release();
  7752. parser->checkJoinFlags($1, $$.queryExpr());
  7753. }
  7754. | NOFOLD '(' dataSet ')'
  7755. {
  7756. $$.setExpr(createDataset(no_nofold, $3.getExpr(), NULL));
  7757. $$.setPosition($1);
  7758. }
  7759. | NOHOIST '(' dataSet ')'
  7760. {
  7761. $$.setExpr(createDataset(no_nohoist, $3.getExpr(), NULL));
  7762. $$.setPosition($1);
  7763. }
  7764. | NOTHOR '(' dataSet ')'
  7765. {
  7766. $$.setExpr(createDataset(no_nothor, $3.getExpr(), NULL));
  7767. $$.setPosition($1);
  7768. }
  7769. | NORMALIZE '(' startLeftSeqFilter ',' expression ',' beginCounterScope transform endCounterScope optCommonAttrs ')' endSelectorSequence
  7770. {
  7771. parser->normalizeExpression($5, type_numeric, false);
  7772. IHqlExpression * counter = $9.getExpr();
  7773. if (counter)
  7774. counter = createAttribute(_countProject_Atom, counter);
  7775. IHqlExpression * extra = createComma($5.getExpr(), $8.getExpr(), counter, createComma($10.getExpr(), $12.getExpr()));
  7776. $$.setExpr(createDataset(no_normalize, $3.getExpr(), extra));
  7777. $$.setPosition($1);
  7778. }
  7779. | NORMALIZE '(' startLeftSeqFilter ',' startRightFilter ',' beginCounterScope transform endCounterScope optCommonAttrs ')' endSelectorSequence
  7780. {
  7781. //NB: SelSeq is based only on the left dataset, not the right as well.
  7782. IHqlExpression * counter = $9.getExpr();
  7783. if (counter)
  7784. counter = createAttribute(_countProject_Atom, counter);
  7785. IHqlExpression * extra = createComma($5.getExpr(), $8.getExpr(), counter, createComma($10.getExpr(), $12.getExpr()));
  7786. $$.setExpr(createDataset(no_normalize, $3.getExpr(), extra));
  7787. $$.setPosition($1);
  7788. }
  7789. /*
  7790. * Needs more thought on the representation - so we can track distributions etc.
  7791. * and need to implement an activity to generate it.
  7792. | NORMALIZE '(' startLeftSeqFilter ',' startLeftRowsGroup ',' beginCounterScope dataSet endCounterScope optCommonAttrs ')' endRowsGroup endSelectorSequence
  7793. {
  7794. parser->checkGrouped($3);
  7795. IHqlExpression * counter = $9.getExpr();
  7796. if (counter)
  7797. counter = createAttribute(_countProject_Atom, counter);
  7798. IHqlExpression *attr = createComma($10.getExpr(), $12.getExpr(), $13.getExpr());
  7799. $$.setExpr(createDataset(no_normalizegroup, $3.getExpr(), createComma($8.getExpr(), counter, attr)));
  7800. $$.setPosition($1);
  7801. }
  7802. */
  7803. | GROUP '(' startTopFilter startGROUP beginList sortList endGROUP
  7804. {
  7805. HqlExprArray sortItems;
  7806. parser->endList(sortItems);
  7807. OwnedHqlExpr input = $3.getExpr();
  7808. OwnedHqlExpr attrs;
  7809. IHqlExpression *groupOrder = parser->processSortList($6, no_group, input, sortItems, NULL, &attrs);
  7810. OwnedHqlExpr args = createComma(groupOrder, LINK(attrs));
  7811. $$.setExpr(createDataset(no_group, input.getClear(), args.getClear()), $1);
  7812. }
  7813. | GROUPED '(' startTopFilter startGROUP beginList sortList endGROUP
  7814. {
  7815. HqlExprArray sortItems;
  7816. parser->endList(sortItems);
  7817. IHqlExpression *input = $3.getExpr();
  7818. OwnedHqlExpr attrs;
  7819. IHqlExpression *groupOrder = parser->processSortList($6, no_group, input, sortItems, NULL, &attrs);
  7820. IHqlExpression *args = createComma(groupOrder, attrs.getClear());
  7821. $$.setExpr(createDataset(no_grouped, input, args), $1);
  7822. }
  7823. | GROUP '(' startTopFilter ')' endTopFilter
  7824. {
  7825. IHqlExpression *input = $3.getExpr();
  7826. $$.setExpr(createDataset(no_group, input, NULL));
  7827. $$.setPosition($1);
  7828. }
  7829. | GROUP '(' startTopFilter startGROUP beginList ROW endGROUP ignoreDummyList
  7830. {
  7831. IHqlExpression *input = $3.getExpr();
  7832. $$.setExpr(createDataset(no_group, input, createComma(getActiveTableSelector(), createLocalAttribute())));
  7833. $$.setPosition($1);
  7834. }
  7835. | REGROUP '(' dataSetList ')'
  7836. {
  7837. OwnedHqlExpr ds = $3.getExpr();
  7838. HqlExprArray args;
  7839. ds->unwindList(args, no_comma);
  7840. parser->checkRegrouping($3, args);
  7841. $$.setExpr(createDataset(no_regroup, args));
  7842. $$.setPosition($1);
  7843. }
  7844. | HAVING '(' startLeftRowsSeqFilter ',' condList ')' endRowsGroup endSelectorSequence
  7845. {
  7846. parser->checkGrouped($3);
  7847. IHqlExpression *attr = NULL; // possibly local may make sense if thor supported it as a global operation, but it would be too painful.
  7848. $$.setExpr(createDataset(no_filtergroup, $3.getExpr(), createComma($5.getExpr(), attr, $7.getExpr(), $8.getExpr())));
  7849. $$.setPosition($1);
  7850. }
  7851. | KEYED '(' dataSet indexListOpt ')' endTopFilter
  7852. {
  7853. IHqlExpression * dataset = $3.getExpr();
  7854. IHqlExpression * indices = $4.getExpr();
  7855. $$.setExpr(createDataset(no_keyed, dataset, indices));
  7856. $$.setPosition($1);
  7857. }
  7858. | UNGROUP '(' startTopFilter ')' endTopFilter
  7859. {
  7860. IHqlExpression *input = $3.getExpr();
  7861. $$.setExpr(createDataset(no_group, input, NULL));
  7862. $$.setPosition($1);
  7863. }
  7864. | TABLE '(' startTopFilter ',' recordDef beginList optSortList ')' endTopFilter
  7865. {
  7866. HqlExprArray sortItems;
  7867. parser->endList(sortItems);
  7868. OwnedHqlExpr dataset = $3.getExpr();
  7869. parser->checkOutputRecord($5, false);
  7870. OwnedHqlExpr record = $5.getExpr();
  7871. OwnedHqlExpr attrs;
  7872. OwnedHqlExpr grouping = parser->processSortList($7, no_usertable, dataset, sortItems, NULL, &attrs);
  7873. if (grouping && !queryAttributeInList(groupedAtom, attrs))
  7874. {
  7875. parser->checkGrouping($7, dataset,record,grouping);
  7876. if (dataset->getOperator() == no_group && isGrouped(dataset))
  7877. parser->reportWarning(WRN_GROUPINGIGNORED, $3.pos, "Grouping of table input will have no effect, was this intended?");
  7878. }
  7879. HqlExprArray args;
  7880. args.append(*LINK(dataset));
  7881. args.append(*LINK(record));
  7882. if (grouping)
  7883. args.append(*LINK(grouping));
  7884. if (attrs)
  7885. attrs->unwindList(args, no_comma);
  7886. //appendUniqueId();
  7887. $$.setExpr(createDataset(no_usertable, args));
  7888. parser->checkProjectedFields($$.queryExpr(), $5);
  7889. $$.setPosition($1);
  7890. }
  7891. | TABLE '(' startTopFilter ',' transform ')' endTopFilter
  7892. {
  7893. OwnedHqlExpr tform = $5.getExpr();
  7894. $$.setExpr(createDataset(no_newusertable, $3.getExpr(), createComma(LINK(tform->queryRecord()), ensureTransformType(tform, no_newtransform))));
  7895. $$.setPosition($1);
  7896. }
  7897. | TABLE '(' startTopFilter ')' endTopFilter
  7898. {
  7899. $$.setExpr(createDataset(no_dataset_alias, $3.getExpr(), ::createUniqueId()), $1);
  7900. }
  7901. | FETCH '(' startLeftDelaySeqFilter ',' startRightFilter ',' expression ',' transform optCommonAttrs ')' endSelectorSequence
  7902. {
  7903. parser->normalizeExpression($7, type_int, false);
  7904. IHqlExpression * left = $3.getExpr();
  7905. IHqlExpression * right = $5.getExpr();
  7906. node_operator modeOp = no_none;
  7907. if (left->getOperator() == no_table)
  7908. modeOp = left->queryChild(2)->getOperator();
  7909. if ((modeOp != no_thor) && (modeOp != no_flat) && (modeOp != no_csv) && (modeOp != no_xml))
  7910. parser->reportError(ERR_FETCH_NON_DATASET, $3, "First parameter of FETCH should be a disk file");
  7911. IHqlExpression *join = createDataset(no_fetch, left, createComma(right, $7.getExpr(), $9.getExpr(), createComma($10.getExpr(), $12.getExpr())));
  7912. $$.setExpr(join);
  7913. $$.setPosition($1);
  7914. }
  7915. | FETCH '(' startLeftDelaySeqFilter ',' startRightFilter ',' expression optCommonAttrs ')' endSelectorSequence
  7916. {
  7917. parser->normalizeExpression($7, type_int, false);
  7918. IHqlExpression * left = $3.getExpr();
  7919. IHqlExpression * right = $5.getExpr();
  7920. IHqlExpression * transform = parser->createDefJoinTransform(left, right, $7, $10.queryExpr(),NULL);
  7921. node_operator modeOp = no_none;
  7922. if (left->getOperator() == no_table)
  7923. modeOp = left->queryChild(2)->getOperator();
  7924. if ((modeOp != no_thor) && (modeOp != no_flat) && (modeOp != no_csv) && (modeOp != no_xml))
  7925. parser->reportError(ERR_FETCH_NON_DATASET, $3, "First parameter of FETCH should be a disk file");
  7926. IHqlExpression *join = createDataset(no_fetch, left, createComma(right, $7.getExpr(), transform, createComma($8.getExpr(), $10.getExpr())));
  7927. $$.setExpr(join);
  7928. $$.setPosition($1);
  7929. }
  7930. | INDEX '(' startTopFilter ',' indexTopRecordAndName optIndexFlags ')' endTopFilter endTopFilter
  7931. {
  7932. IHqlExpression *dataset = $3.getExpr();
  7933. OwnedHqlExpr record = $5.getExpr();
  7934. OwnedHqlExpr extra = $6.getExpr();
  7935. parser->extractIndexRecordAndExtra(record, extra);
  7936. OwnedHqlExpr transform = parser->extractTransformFromExtra(extra);
  7937. parser->inheritRecordMaxLength(dataset, record);
  7938. bool hasFileposition = getBoolAttributeInList(extra, filepositionAtom, true);
  7939. record.setown(parser->checkIndexRecord(record, $5, extra));
  7940. if (transform)
  7941. {
  7942. if (!recordTypesMatch(dataset, transform))
  7943. {
  7944. parser->reportError(ERR_TRANSFORM_TYPE_MISMATCH, $5,"Type returned from transform must match the source dataset type");
  7945. transform.setown(parser->createClearTransform(dataset->queryRecord(), $5));
  7946. }
  7947. //Convert the no_transform to a no_newtransform, because it is currently a bit of a fake.
  7948. HqlExprArray args;
  7949. unwindChildren(args, transform);
  7950. transform.setown(createValue(no_newtransform, transform->getType(), args));
  7951. $$.setExpr(createDataset(no_newkeyindex, dataset, createComma(record.getClear(), transform.getClear(), extra.getClear())));
  7952. }
  7953. else
  7954. $$.setExpr(createDataset(no_keyindex, dataset, createComma(record.getClear(), extra.getClear())));
  7955. parser->checkIndexRecordTypes($$.queryExpr(), $1);
  7956. $$.setPosition($1);
  7957. }
  7958. | INDEX '(' indexTopRecordAndName optIndexFlags ')' endTopFilter
  7959. {
  7960. OwnedHqlExpr record = $3.getExpr();
  7961. OwnedHqlExpr extra = $4.getExpr();
  7962. parser->extractIndexRecordAndExtra(record, extra);
  7963. $$.setExpr(parser->createIndexFromRecord(record, extra, $3));
  7964. parser->checkIndexRecordTypes($$.queryExpr(), $1);
  7965. $$.setPosition($1);
  7966. }
  7967. | INDEX '(' startTopFilter ',' expression optIndexFlags ')' endTopFilter
  7968. {
  7969. parser->normalizeExpression($5, type_string, false);
  7970. OwnedHqlExpr newName = $5.getExpr();
  7971. OwnedHqlExpr dataset = $3.getExpr();
  7972. if (isKey(dataset))
  7973. {
  7974. node_operator keyOp = dataset->getOperator();
  7975. HqlExprArray args;
  7976. unwindChildren(args, dataset);
  7977. if (keyOp == no_keyindex)
  7978. args.replace(*newName.getClear(), 2);
  7979. else
  7980. args.replace(*newName.getClear(), 3);
  7981. $6.unwindCommaList(args);
  7982. dataset.setown(createDataset(keyOp, args));
  7983. }
  7984. else
  7985. parser->reportError(ERR_EXPECTED_INDEX,$3,"Index aliasing syntax - expected an index as the first parameter");
  7986. $$.setExpr(dataset.getClear());
  7987. $$.setPosition($1);
  7988. }
  7989. | DATASET '(' thorFilenameOrList ',' beginCounterScope dsRecordDef endCounterScope ',' mode optDsOptions dsEnd
  7990. {
  7991. OwnedHqlExpr counter = $7.queryExpr();
  7992. if (counter)
  7993. parser->reportError(ERR_ILL_HERE,$6,"Not expecting COUNTER for DATASET");
  7994. parser->warnIfRecordPacked($6);
  7995. parser->transferOptions($3, $10);
  7996. parser->normalizeExpression($3, type_string, false);
  7997. OwnedHqlExpr mode = $9.getExpr();
  7998. OwnedHqlExpr options = $10.getExpr();
  7999. OwnedHqlExpr filename = $3.getExpr();
  8000. if (mode->getOperator() == no_comma)
  8001. {
  8002. //Handle a messy common-grammar production which isn't in the format we want
  8003. assertex(mode->queryChild(0)->getOperator() == no_pipe);
  8004. HqlExprArray args;
  8005. unwindChildren(args, mode->queryChild(0));
  8006. mode->queryChild(1)->unwindList(args, no_comma);
  8007. mode.setown(createValue(no_pipe, makeNullType(), args));
  8008. }
  8009. //LOCAL(expression) is now an overloaded the syntax, so disambiguate here...
  8010. if (filename->getOperator() == no_forcelocal)
  8011. {
  8012. filename.setown(createValue(no_assertconstant, filename->getType(), LINK(filename->queryChild(0))));
  8013. options.setown(createComma(options.getClear(), createAttribute(localUploadAtom)));
  8014. }
  8015. IHqlExpression * dataset = createNewDataset(filename.getClear(), $6.getExpr(), mode.getClear(), NULL, NULL, options.getClear());
  8016. parser->checkValidRecordMode(dataset, $4, $9);
  8017. $$.setExpr(dataset);
  8018. $$.setPosition($1);
  8019. }
  8020. | DATASET '(' thorFilenameOrList ',' beginCounterScope simpleType endCounterScope optDsOptions dsEnd
  8021. {
  8022. OwnedHqlExpr counter = $7.queryExpr();
  8023. if (counter)
  8024. parser->reportError(ERR_ILL_HERE,$6,"Not expecting COUNTER for DATASET");
  8025. parser->transferOptions($3, $8);
  8026. parser->normalizeExpression($3, type_string, false);
  8027. OwnedHqlExpr options = $8.getExpr();
  8028. OwnedITypeInfo type = $6.getType();
  8029. OwnedHqlExpr filename = $3.getExpr();
  8030. OwnedHqlExpr option;
  8031. switch (type->getTypeCode())
  8032. {
  8033. case type_string:
  8034. option.setown(createAttribute(asciiAtom));
  8035. break;
  8036. case type_utf8:
  8037. case type_unicode:
  8038. option.setown(createAttribute(unicodeAtom));
  8039. break;
  8040. default:
  8041. parser->reportError(ERR_EXPECTED, $1, "Expected STRING/UTF8/UNICODE");
  8042. }
  8043. OwnedHqlExpr empty = createList(no_list, makeSetType(NULL), NULL);
  8044. OwnedHqlExpr quoted = createExprAttribute(quoteAtom, LINK(empty));
  8045. OwnedHqlExpr separator = createExprAttribute(separatorAtom, LINK(empty));
  8046. OwnedHqlExpr mode = createValue(no_csv, makeNullType(), quoted.getClear(), separator.getClear(), option.getClear());
  8047. OwnedHqlExpr field = createField(lineId, LINK(type), NULL);
  8048. OwnedHqlExpr record = createRecord(field);
  8049. //LOCAL(expression) is now an overloaded the syntax, so disambiguate here...
  8050. if (filename->getOperator() == no_forcelocal)
  8051. {
  8052. filename.setown(createValue(no_assertconstant, filename->getType(), LINK(filename->queryChild(0))));
  8053. options.setown(createComma(options.getClear(), createAttribute(localUploadAtom)));
  8054. }
  8055. IHqlExpression * dataset = createNewDataset(filename.getClear(), record.getClear(), mode.getClear(), NULL, NULL, options.getClear());
  8056. parser->checkValidRecordMode(dataset, $4, $9);
  8057. $$.setExpr(dataset, $1);
  8058. }
  8059. | DATASET '(' dataSet ',' thorFilenameOrList ',' mode optDsOptions dsEnd
  8060. {
  8061. parser->warnIfRecordPacked($3);
  8062. parser->transferOptions($5, $8);
  8063. parser->normalizeExpression($5, type_string, false);
  8064. IHqlExpression * origin = $3.getExpr();
  8065. IHqlExpression * filename = $5.getExpr();
  8066. IHqlExpression * mode = $7.getExpr();
  8067. IHqlExpression * attrs = createComma(createAttribute(_origin_Atom, origin), $8.getExpr());
  8068. IHqlExpression * dataset = createNewDataset(filename, LINK(origin->queryRecord()), mode, NULL, NULL, attrs);
  8069. parser->checkValidRecordMode(dataset, $4, $7);
  8070. $$.setExpr(dataset);
  8071. $$.setPosition($1);
  8072. }
  8073. | DATASET '(' '[' beginList inlineDatasetValueList ']' ',' recordDef ')'
  8074. {
  8075. HqlExprArray values;
  8076. parser->endList(values);
  8077. OwnedHqlExpr table = createDataset(no_temptable, createValue(no_recordlist, NULL, values), $8.getExpr());
  8078. $$.setExpr(convertTempTableToInlineTable(*parser->errorHandler, $5.pos, table));
  8079. $$.setPosition($1);
  8080. }
  8081. | DATASET '(' '[' beginList transformList ']' ')'
  8082. {
  8083. HqlExprArray values;
  8084. parser->endList(values);
  8085. IHqlExpression * record = values.item(0).queryRecord();
  8086. parser->checkCompatibleTransforms(values, record, $5);
  8087. $$.setExpr(createDataset(no_inlinetable, createValue(no_transformlist, makeNullType(), values), LINK(record)));
  8088. $$.setPosition($1);
  8089. }
  8090. | DATASET '(' thorFilenameOrList ',' beginCounterScope recordDef endCounterScope ')'
  8091. {
  8092. //NB: $3 is required to be a list, but uses thorfilename production to work around a s/r error
  8093. OwnedHqlExpr counter = $7.queryExpr();
  8094. if (counter)
  8095. parser->reportError(ERR_ILL_HERE,$6,"Not expecting COUNTER for DATASET");
  8096. parser->normalizeExpression($3, type_set, false);
  8097. $$.setExpr(parser->createDatasetFromList($3, $6), $1);
  8098. }
  8099. | DATASET '(' WORKUNIT '(' expression ',' expression ')' ',' recordDef ')'
  8100. {
  8101. parser->normalizeExpression($5, type_scalar, false);
  8102. parser->normalizeExpression($7, type_scalar, false);
  8103. IHqlExpression * wuid = createExprAttribute(wuidAtom, $5.getExpr());
  8104. IHqlExpression * arg = $7.getExpr();
  8105. if (isStringType(arg->queryType()))
  8106. {
  8107. arg = createAttribute(nameAtom, arg);
  8108. arg = createComma(createAttribute(sequenceAtom, createConstant(0)), arg);
  8109. }
  8110. else
  8111. arg = createAttribute(sequenceAtom, arg);
  8112. $$.setExpr(createDataset(no_workunit_dataset, $10.getExpr(), createComma(wuid, arg)));
  8113. $$.setPosition($1);
  8114. }
  8115. | DATASET '(' WORKUNIT '(' expression ')' ',' recordDef ')'
  8116. {
  8117. parser->normalizeExpression($5, type_scalar, false);
  8118. IHqlExpression * arg = $5.getExpr();
  8119. if (isStringType(arg->queryType()))
  8120. {
  8121. arg = createAttribute(nameAtom, arg);
  8122. arg = createComma(createAttribute(sequenceAtom, createConstant(0)), arg);
  8123. }
  8124. else
  8125. arg = createAttribute(sequenceAtom, arg);
  8126. $$.setExpr(createDataset(no_workunit_dataset, $8.getExpr(), arg));
  8127. $$.setPosition($1);
  8128. }
  8129. | DATASET '(' thorFilenameOrList ',' beginCounterScope transform endCounterScope optDatasetFlags ')'
  8130. {
  8131. parser->normalizeExpression($3, type_int, false);
  8132. IHqlExpression * counter = $7.getExpr();
  8133. if (counter)
  8134. counter = createAttribute(_countProject_Atom, counter);
  8135. OwnedHqlExpr options = $8.getExpr();
  8136. if (options)
  8137. {
  8138. if (options->numChildren() > 0)
  8139. parser->reportError(ERR_DSPARAM_INVALIDOPTCOMB, $8, "The DATASET options DISTRIBUTED, LOCAL, and NOLOCAL are not permutable.");
  8140. }
  8141. $$.setExpr(createDataset(no_dataset_from_transform, $3.getExpr(), createComma($6.getExpr(), counter, options.getClear())));
  8142. $$.setPosition($1);
  8143. }
  8144. | ENTH '(' dataSet ',' expression optCommonAttrs ')'
  8145. {
  8146. parser->normalizeExpression($5, type_numeric, false);
  8147. $$.setExpr(createDataset(no_enth, $3.getExpr(), createComma($5.getExpr(), $6.getExpr())));
  8148. $$.setPosition($1);
  8149. }
  8150. | ENTH '(' dataSet ',' expression ',' expression optCommonAttrs ')'
  8151. {
  8152. parser->normalizeExpression($5, type_numeric, false);
  8153. parser->normalizeExpression($7, type_numeric, false);
  8154. $$.setExpr(createDataset(no_enth, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $8.getExpr())));
  8155. $$.setPosition($1);
  8156. }
  8157. | ENTH '(' dataSet ',' expression ',' expression ',' expression optCommonAttrs ')'
  8158. {
  8159. parser->normalizeExpression($5, type_numeric, false);
  8160. parser->normalizeExpression($7, type_numeric, false);
  8161. parser->normalizeExpression($9, type_numeric, false);
  8162. $$.setExpr(createDataset(no_enth, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), $10.getExpr())));
  8163. $$.setPosition($1);
  8164. }
  8165. | PIPE '(' expression ',' recordDef optPipeOptions ')'
  8166. {
  8167. parser->normalizeExpression($3, type_string, false);
  8168. parser->checkValidPipeRecord($5, $5.queryExpr(), $6.queryExpr(), NULL);
  8169. $$.setExpr(createNewDataset(createConstant(""), $5.getExpr(), createValue(no_pipe, makeNullType(), $3.getExpr()), NULL, NULL, $6.getExpr()));
  8170. $$.setPosition($1);
  8171. }
  8172. | PIPE '(' startTopFilter ',' expression optPipeOptions endTopFilter ')'
  8173. {
  8174. parser->normalizeExpression($5, type_string, false);
  8175. OwnedHqlExpr attrs = $6.getExpr();
  8176. parser->checkValidPipeRecord($3, $3.queryExpr()->queryRecord(), attrs, NULL);
  8177. parser->checkValidPipeRecord($3, $3.queryExpr()->queryRecord(), NULL, queryAttributeInList(outputAtom, attrs));
  8178. $$.setExpr(createDataset(no_pipe, $3.getExpr(), createComma($5.getExpr(), LINK(attrs))));
  8179. $$.setPosition($1);
  8180. }
  8181. | PIPE '(' startTopFilter ',' expression ',' recordDef optPipeOptions endTopFilter ')'
  8182. {
  8183. parser->normalizeExpression($5, type_string, false);
  8184. OwnedHqlExpr attrs = $8.getExpr();
  8185. parser->checkValidPipeRecord($3, $3.queryExpr()->queryRecord(), NULL, queryAttributeInList(outputAtom, attrs));
  8186. parser->checkValidPipeRecord($7, $7.queryExpr()->queryRecord(), attrs, NULL);
  8187. $$.setExpr(createDataset(no_pipe, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), LINK(attrs))));
  8188. $$.setPosition($1);
  8189. }
  8190. | PRELOAD '(' dataSet optConstExpression ')'
  8191. {
  8192. $$.setExpr(createDataset(no_preload, $3.getExpr(), $4.getExpr()));
  8193. $$.setPosition($1);
  8194. }
  8195. | SAMPLE '(' startTopFilter ',' const ')' endTopFilter
  8196. {
  8197. $$.setExpr(createDataset(no_sample, $3.getExpr(), $5.getExpr()));
  8198. $$.setPosition($1);
  8199. }
  8200. | SAMPLE '(' startTopFilter ',' const ',' const ')' endTopFilter
  8201. {
  8202. $$.setExpr(createDataset(no_sample, $3.getExpr(), createComma($5.getExpr(), $7.getExpr())));
  8203. $$.setPosition($1);
  8204. }
  8205. | TOPN '(' startTopFilter ',' expression ',' startSortOrder beginList sortListOptCurleys ')' endSortOrder endTopFilter
  8206. {
  8207. HqlExprArray sortItems;
  8208. parser->endList(sortItems);
  8209. parser->normalizeExpression($5, type_int, false);
  8210. IHqlExpression* dataset = $3.queryExpr();
  8211. IHqlExpression *input = $3.getExpr();
  8212. OwnedHqlExpr attrs;
  8213. IHqlExpression *sortOrder = parser->processSortList($9, no_topn, dataset, sortItems, NULL, &attrs);
  8214. if (!sortOrder)
  8215. {
  8216. parser->reportError(ERR_SORT_EMPTYLIST, $1, "The list to be sorted on is empty");
  8217. $$.setExpr(input);
  8218. }
  8219. else
  8220. {
  8221. IHqlExpression * best = queryAttributeInList(bestAtom, attrs);
  8222. if (best)
  8223. parser->checkMaxCompatible(sortOrder, best, $9);
  8224. bool isLocal = (queryAttributeInList(localAtom, attrs)!=NULL);
  8225. parser->checkDistribution($3, input, isLocal, false);
  8226. attrs.setown(createComma(sortOrder, $5.getExpr(), LINK(attrs)));
  8227. $$.setExpr(createDataset(no_topn, input, attrs.getClear()));
  8228. }
  8229. $$.setPosition($1);
  8230. }
  8231. | SORT '(' startSortOrder startTopFilter ',' beginList sortListOptCurleys ')' endSortOrder endTopFilter
  8232. {
  8233. HqlExprArray sortItems;
  8234. parser->endList(sortItems);
  8235. $$.setExpr(parser->createSortExpr(no_sort, $4, $7, sortItems));
  8236. $$.setPosition($1);
  8237. }
  8238. | SUBSORT '(' startSortOrder startTopFilter ',' sortListExpr ',' sortListExpr optCommonAttrs ')' endSortOrder endTopFilter
  8239. {
  8240. OwnedHqlExpr options = $9.getExpr();
  8241. if (isGrouped($4.queryExpr()))
  8242. parser->reportError(HQLERR_CannotBeGrouped, $1, "SUBSORT not yet supported on grouped datasets");
  8243. //NB: $6 and $8 are reversed in their internal representation to make consistent with no_sort
  8244. $$.setExpr(createDataset(no_subsort, $4.getExpr(), createComma($8.getExpr(), $6.getExpr(), options.getClear())), $1);
  8245. }
  8246. | SORTED '(' startSortOrder startTopFilter ',' beginList sortListOptCurleys ')' endSortOrder endTopFilter
  8247. {
  8248. HqlExprArray sortItems;
  8249. parser->endList(sortItems);
  8250. $$.setExpr(parser->createSortExpr(no_sorted, $4, $7, sortItems));
  8251. $$.setPosition($1);
  8252. }
  8253. | SORTED '(' startSortOrder dataSet ')' endSortOrder
  8254. {
  8255. OwnedHqlExpr dataset = $4.getExpr();
  8256. HqlExprArray args, sorted;
  8257. IHqlExpression * record = dataset->queryRecord();
  8258. unwindRecordAsSelects(sorted, record, dataset->queryNormalizedSelector());
  8259. args.append(*dataset.getClear());
  8260. args.append(*createSortList(sorted));
  8261. $$.setExpr(createDataset(no_sorted, args));
  8262. $$.setPosition($1);
  8263. }
  8264. | STEPPED '(' startTopFilter ',' expressionList optStepFlags ')' endTopFilter
  8265. {
  8266. OwnedHqlExpr dataset = $3.getExpr();
  8267. HqlExprArray args;
  8268. $5.unwindCommaList(args);
  8269. OwnedHqlExpr stepOrder = createSortList(args);
  8270. $$.setExpr(createDatasetF(no_stepped, dataset.getClear(), stepOrder.getClear(), $6.getExpr(), NULL));
  8271. $$.setPosition($1);
  8272. }
  8273. | '(' dataSet ')' {
  8274. $$.setExpr($2.getExpr());
  8275. $$.setPosition($1);
  8276. }
  8277. | IF '(' booleanExpr ',' dataSet ',' dataSet ')'
  8278. {
  8279. OwnedHqlExpr ds = parser->processIfProduction($3, $5, &$7);
  8280. $$.setExpr(ds.getClear(), $1);
  8281. }
  8282. | IF '(' booleanExpr ',' dataSet ')'
  8283. {
  8284. OwnedHqlExpr ds = parser->processIfProduction($3, $5, NULL);
  8285. $$.setExpr(ds.getClear(), $1);
  8286. }
  8287. | IFF '(' booleanExpr ',' dataSet ',' dataSet ')'
  8288. {
  8289. OwnedHqlExpr ds = parser->processIfProduction($3, $5, &$7);
  8290. $$.setExpr(ds.getClear(), $1);
  8291. }
  8292. | IFF '(' booleanExpr ',' dataSet ')'
  8293. {
  8294. OwnedHqlExpr ds = parser->processIfProduction($3, $5, NULL);
  8295. $$.setExpr(ds.getClear(), $1);
  8296. }
  8297. | MAP '(' mapDatasetSpec ',' dataSet ')'
  8298. {
  8299. HqlExprArray args;
  8300. OwnedHqlExpr elseExpr = $5.getExpr();
  8301. $3.unwindCommaList(args);
  8302. parser->ensureMapToRecordsMatch(elseExpr, args, $5, false);
  8303. args.append(*elseExpr.getClear());
  8304. $$.setExpr(::createDataset(no_map, args));
  8305. $$.setPosition($1);
  8306. }
  8307. | MAP '(' mapDatasetSpec ')'
  8308. {
  8309. HqlExprArray args;
  8310. $3.unwindCommaList(args);
  8311. OwnedHqlExpr elseExpr;
  8312. if (args.ordinality())
  8313. elseExpr.setown(createNullExpr(&args.item(0)));
  8314. else
  8315. elseExpr.setown(createDataset(no_null, LINK(queryNullRecord())));
  8316. parser->ensureMapToRecordsMatch(elseExpr, args, $3, false);
  8317. args.append(*elseExpr.getClear());
  8318. $$.setExpr(::createDataset(no_map, args));
  8319. $$.setPosition($1);
  8320. }
  8321. | CASE '(' expression ',' beginList caseDatasetSpec ',' dataSet ')'
  8322. {
  8323. parser->normalizeExpression($3, type_scalar, false);
  8324. HqlExprArray args;
  8325. OwnedHqlExpr elseExpr = $8.getExpr();
  8326. parser->endList(args);
  8327. parser->checkCaseForDuplicates(args, $6);
  8328. parser->ensureMapToRecordsMatch(elseExpr, args, $8, false);
  8329. args.add(*$3.getExpr(),0);
  8330. args.append(*elseExpr.getClear());
  8331. $$.setExpr(::createDataset(no_case, args));
  8332. $$.setPosition($1);
  8333. }
  8334. | CASE '(' expression ',' beginList caseDatasetSpec ')'
  8335. {
  8336. parser->normalizeExpression($3, type_scalar, false);
  8337. HqlExprArray args;
  8338. parser->endList(args);
  8339. OwnedHqlExpr elseDs;
  8340. if (args.ordinality())
  8341. elseDs.setown(createNullExpr(&args.item(0)));
  8342. else
  8343. elseDs.setown(createDataset(no_null, LINK(queryNullRecord())));
  8344. parser->checkCaseForDuplicates(args, $6);
  8345. parser->ensureMapToRecordsMatch(elseDs, args, $6, false);
  8346. args.add(*$3.getExpr(),0);
  8347. args.append(*elseDs.getClear());
  8348. $$.setExpr(::createDataset(no_case, args));
  8349. $$.setPosition($1);
  8350. }
  8351. | CASE '(' expression ',' beginList dataSet ')'
  8352. {
  8353. parser->normalizeExpression($3, type_scalar, false);
  8354. // change error to warning.
  8355. parser->reportWarning(WRN_CASENOCONDITION, $1.pos, "CASE does not have any conditions");
  8356. HqlExprArray list;
  8357. parser->endList(list);
  8358. $3.release();
  8359. $$.setExpr($6.getExpr(), $1);
  8360. }
  8361. | CHOOSE '(' expression ',' mergeDataSetList ')'
  8362. {
  8363. parser->normalizeExpression($3, type_int, false);
  8364. OwnedHqlExpr values = $5.getExpr();
  8365. HqlExprArray unorderedArgs;
  8366. values->unwindList(unorderedArgs, no_comma);
  8367. HqlExprArray args;
  8368. reorderAttributesToEnd(args, unorderedArgs);
  8369. IHqlExpression * compareDs = NULL;
  8370. ForEachItemIn(idx, args)
  8371. {
  8372. IHqlExpression * cur = &args.item(idx);
  8373. if (cur->queryRecord())
  8374. {
  8375. if (compareDs)
  8376. {
  8377. if (isGrouped(cur) != isGrouped(compareDs))
  8378. parser->reportError(ERR_GROUPING_MISMATCH, $1, "Branches of the condition have different grouping");
  8379. OwnedHqlExpr mapped = parser->checkEnsureRecordsMatch(compareDs, cur, $5, false);
  8380. if (mapped != cur)
  8381. args.replace(*mapped.getClear(), idx);
  8382. }
  8383. else
  8384. compareDs = cur;
  8385. }
  8386. }
  8387. args.add(*$3.getExpr(), 0);
  8388. $$.setExpr(createDataset(no_chooseds, args), $1);
  8389. }
  8390. | PARSE '(' startTopLeftSeqFilter ',' expression ',' startRootPattern ',' recordDef endRootPattern endTopLeftFilter doParseFlags ')' endSelectorSequence
  8391. {
  8392. parser->normalizeExpression($5, type_stringorunicode, false);
  8393. parser->checkOutputRecord($9, false);
  8394. IHqlExpression * ds = createDataset(no_parse, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), createComma($12.getExpr(), $14.getExpr())));
  8395. if (ds->hasAttribute(tomitaAtom) && (ds->queryChild(2)->queryType()->getTypeCode() == type_pattern))
  8396. parser->reportError(ERR_EXPECTED_RULE, $7, "Expected a rule as parameter to PARSE");
  8397. $$.setExpr(ds);
  8398. $$.setPosition($1);
  8399. }
  8400. | PARSE '(' startTopLeftSeqFilter ',' expression ',' startRootPattern ',' transform endRootPattern endTopLeftFilter doParseFlags ')' endSelectorSequence
  8401. {
  8402. parser->normalizeExpression($5, type_stringorunicode, false);
  8403. IHqlExpression * record = $9.queryExpr()->queryRecord();
  8404. IHqlExpression * ds = createDataset(no_newparse, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), LINK(record), createComma($9.getExpr(), $12.getExpr(), $14.getExpr())));
  8405. if (ds->hasAttribute(tomitaAtom) && (ds->queryChild(2)->queryType()->getTypeCode() == type_pattern))
  8406. parser->reportError(ERR_EXPECTED_RULE, $7, "Expected a rule as parameter to PARSE");
  8407. $$.setExpr(ds);
  8408. $$.setPosition($1);
  8409. }
  8410. | PARSE '(' startTopLeftSeqFilter ',' expression ',' transform endTopLeftFilter xmlParseFlags ')' endSelectorSequence
  8411. {
  8412. parser->normalizeExpression($5, type_stringorunicode, false);
  8413. IHqlExpression * record = $7.queryExpr()->queryRecord();
  8414. $$.setExpr(createDataset(no_newxmlparse, $3.getExpr(), createComma($5.getExpr(), LINK(record), $7.getExpr(), createComma($9.getExpr(), $11.getExpr()))));
  8415. $$.setPosition($1);
  8416. }
  8417. | PARSE '(' startTopLeftSeqFilter ',' expression ',' recordDef endTopLeftFilter xmlParseFlags ')' endSelectorSequence
  8418. {
  8419. parser->normalizeExpression($5, type_stringorunicode, false);
  8420. parser->checkOutputRecord($7, false);
  8421. $$.setExpr(createDataset(no_xmlparse, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), $11.getExpr())));
  8422. $$.setPosition($1);
  8423. }
  8424. | FAIL '(' recordDef failDatasetParam ')'
  8425. {
  8426. //Actually allow a sequence of arbitrary actions....
  8427. $$.setExpr(createDataset(no_fail, $3.getExpr(), $4.getExpr()));
  8428. $$.setPosition($1);
  8429. }
  8430. | FAIL '(' dataSet failDatasetParam ')'
  8431. {
  8432. OwnedHqlExpr ds = $3.getExpr();
  8433. //Actually allow a sequence of arbitrary actions....
  8434. $$.setExpr(createDataset(no_fail, LINK(ds->queryRecord()), $4.getExpr()));
  8435. $$.setPosition($1);
  8436. }
  8437. | TOK_ERROR '(' recordDef failDatasetParam ')'
  8438. {
  8439. //Actually allow a sequence of arbitrary actions....
  8440. $$.setExpr(createDataset(no_fail, $3.getExpr(), $4.getExpr()));
  8441. $$.setPosition($1);
  8442. }
  8443. | TOK_ERROR '(' dataSet failDatasetParam ')'
  8444. {
  8445. OwnedHqlExpr ds = $3.getExpr();
  8446. //Actually allow a sequence of arbitrary actions....
  8447. $$.setExpr(createDataset(no_fail, LINK(ds->queryRecord()), $4.getExpr()));
  8448. $$.setPosition($1);
  8449. }
  8450. | SKIP '(' recordDef ')'
  8451. {
  8452. if (!parser->curTransform)
  8453. parser->reportError(ERR_PARSER_CANNOTRECOVER,$1,"SKIP is only valid inside a TRANSFORM");
  8454. $$.setExpr(createDataset(no_skip, $3.getExpr()));
  8455. }
  8456. | SOAPCALL '(' expression ',' expression ',' recordDef ',' DATASET '(' recordDef ')' ')'
  8457. {
  8458. parser->normalizeExpression($3);
  8459. parser->normalizeExpression($5);
  8460. parser->checkSoapRecord($7);
  8461. $$.setExpr(createDataset(no_soapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $11.getExpr())));
  8462. $$.setPosition($1);
  8463. }
  8464. | SOAPCALL '(' expression ',' expression ',' recordDef ',' DATASET '(' recordDef ')' ',' soapFlags ')'
  8465. {
  8466. parser->normalizeExpression($3);
  8467. parser->normalizeExpression($5);
  8468. parser->checkSoapRecord($7);
  8469. $$.setExpr(createDataset(no_soapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $11.getExpr(), $14.getExpr())));
  8470. parser->checkOnFailRecord($$.queryExpr(), $1);
  8471. $$.setPosition($1);
  8472. }
  8473. | SOAPCALL '(' expression ',' expression ',' recordDef ',' transform ',' DATASET '(' recordDef ')' ')'
  8474. {
  8475. parser->normalizeExpression($3);
  8476. parser->normalizeExpression($5);
  8477. $$.setExpr(createDataset(no_newsoapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), $13.getExpr())));
  8478. $$.setPosition($1);
  8479. }
  8480. | SOAPCALL '(' expression ',' expression ',' recordDef ',' transform ',' DATASET '(' recordDef ')' ',' soapFlags ')'
  8481. {
  8482. parser->normalizeExpression($3);
  8483. parser->normalizeExpression($5);
  8484. $$.setExpr(createDataset(no_newsoapcall, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), createComma($13.getExpr(), $16.getExpr()))));
  8485. parser->checkOnFailRecord($$.queryExpr(), $1);
  8486. $$.setPosition($1);
  8487. }
  8488. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ',' DATASET '(' recordDef ')' ')' endTopLeftFilter endSelectorSequence
  8489. {
  8490. parser->normalizeExpression($5);
  8491. parser->normalizeExpression($7);
  8492. parser->checkSoapRecord($9);
  8493. $$.setExpr(createDataset(no_soapcall_ds, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), createComma($13.getExpr(), $17.getExpr()))));
  8494. $$.setPosition($1);
  8495. }
  8496. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ',' DATASET '(' recordDef ')' ',' soapFlags ')' endTopLeftFilter endSelectorSequence
  8497. {
  8498. parser->normalizeExpression($5);
  8499. parser->normalizeExpression($7);
  8500. parser->checkSoapRecord($9);
  8501. $$.setExpr(createDataset(no_soapcall_ds, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), createComma($13.getExpr(), $16.getExpr(), $19.getExpr()))));
  8502. parser->checkOnFailRecord($$.queryExpr(), $1);
  8503. $$.setPosition($1);
  8504. }
  8505. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ',' transform ',' DATASET '(' recordDef ')' ')' endTopLeftFilter endSelectorSequence
  8506. {
  8507. parser->normalizeExpression($5);
  8508. parser->normalizeExpression($7);
  8509. $$.setExpr(createDataset(no_newsoapcall_ds, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), createComma($11.getExpr(), $15.getExpr(), $19.getExpr()))));
  8510. $$.setPosition($1);
  8511. }
  8512. | SOAPCALL '(' startTopLeftSeqFilter ',' expression ',' expression ',' recordDef ',' transform ',' DATASET '(' recordDef ')' ',' soapFlags ')' endTopLeftFilter endSelectorSequence
  8513. {
  8514. parser->normalizeExpression($5);
  8515. parser->normalizeExpression($7);
  8516. $$.setExpr(createDataset(no_newsoapcall_ds, $3.getExpr(), createComma($5.getExpr(), $7.getExpr(), $9.getExpr(), createComma($11.getExpr(), $15.getExpr(), $18.getExpr(), $21.getExpr()))));
  8517. parser->checkOnFailRecord($$.queryExpr(), $1);
  8518. $$.setPosition($1);
  8519. }
  8520. | GLOBAL '(' dataSet globalOpts ')'
  8521. {
  8522. $$.setExpr(createDataset(no_globalscope, $3.getExpr(), $4.getExpr()));
  8523. $$.setPosition($1);
  8524. }
  8525. | GLOBAL '(' dataSet ',' expression globalOpts ')'
  8526. {
  8527. parser->normalizeExpression($5, type_string, false);
  8528. $$.setExpr(createDataset(no_globalscope, $3.getExpr(), createComma($5.getExpr(), $6.getExpr())));
  8529. $$.setPosition($1);
  8530. }
  8531. | LOCAL '(' dataSet ')'
  8532. {
  8533. $$.setExpr(createDataset(no_forcelocal, $3.getExpr()));
  8534. $$.setPosition($1);
  8535. }
  8536. | NOLOCAL '(' dataSet ')'
  8537. {
  8538. $$.setExpr(createDataset(no_forcenolocal, $3.getExpr()));
  8539. $$.setPosition($1);
  8540. }
  8541. | ALLNODES '(' beginList dataSet ignoreDummyList remoteOptions ')'
  8542. {
  8543. OwnedHqlExpr ds = $4.getExpr();
  8544. if (isGrouped(ds))
  8545. parser->reportError(ERR_REMOTE_GROUPED, $1, "ALLNODES() is not currently supported on grouped datasets");
  8546. HqlExprArray args;
  8547. args.append(*LINK(ds));
  8548. $6.unwindCommaList(args);
  8549. IHqlExpression * onFail = queryAttribute(onFailAtom, args);
  8550. if (onFail && !parser->checkTransformTypeMatch($4, ds, onFail->queryChild(0)))
  8551. args.zap(*onFail);
  8552. $$.setExpr(createDataset(no_allnodes, args));
  8553. $$.setPosition($1);
  8554. }
  8555. | THISNODE '(' dataSet ')'
  8556. {
  8557. $$.setExpr(createDataset(no_thisnode, $3.getExpr()));
  8558. $$.setPosition($1);
  8559. }
  8560. | DATASET '(' dataRow ')'
  8561. {
  8562. IHqlExpression * row = $3.getExpr();
  8563. $$.setExpr(createDatasetFromRow(row));
  8564. $$.setPosition($1);
  8565. }
  8566. | DATASET '(' dictionary ')'
  8567. {
  8568. IHqlExpression * dictionary = $3.getExpr();
  8569. $$.setExpr(createDataset(no_datasetfromdictionary, dictionary), $1);
  8570. }
  8571. | _EMPTY_ '(' recordDef ')'
  8572. {
  8573. IHqlExpression * record = $3.getExpr();
  8574. $$.setExpr(createDataset(no_null, record));
  8575. $$.setPosition($1);
  8576. }
  8577. | __COMPOUND__ '(' action ',' dataSet ')'
  8578. {
  8579. if (parser->okToAddSideEffects($5.queryExpr()))
  8580. {
  8581. $$.setExpr(createCompound($3.getExpr(), $5.getExpr()));
  8582. }
  8583. else
  8584. {
  8585. $3.release();
  8586. $$.setExpr($5.getExpr());
  8587. }
  8588. $$.setPosition($1);
  8589. }
  8590. | __COMMON__ '(' dataSet ')'
  8591. {
  8592. $$.setExpr(createAliasOwn($3.getExpr(), NULL));
  8593. $$.setPosition($1);
  8594. }
  8595. | TOK_ASSERT '(' startTopFilter ',' expression assertFlags ')' endTopFilter
  8596. {
  8597. parser->normalizeExpression($5);
  8598. IHqlExpression * action = parser->createAssert($5, NULL, $6);
  8599. $$.setExpr(createDataset(no_assert_ds, $3.getExpr(), action));
  8600. $$.setPosition($1);
  8601. }
  8602. | TOK_ASSERT '(' startTopFilter ',' expression ',' expression assertFlags ')' endTopFilter
  8603. {
  8604. parser->normalizeExpression($5);
  8605. parser->normalizeExpression($7);
  8606. IHqlExpression * action = parser->createAssert($5, &$7, $8);
  8607. $$.setExpr(createDataset(no_assert_ds, $3.getExpr(), action));
  8608. //MORE: This should possibly be a more general no_throughapply
  8609. $$.setPosition($1);
  8610. }
  8611. | TOK_ASSERT '(' startTopFilter ',' assertActions ')' endTopFilter
  8612. {
  8613. $$.setExpr(createDataset(no_assert_ds, $3.getExpr(), $5.getExpr()));
  8614. //MORE: This should possibly be a more general no_throughapply
  8615. $$.setPosition($1);
  8616. }
  8617. | ROWS '(' dataRow ')'
  8618. {
  8619. OwnedHqlExpr ds = $3.getExpr();
  8620. $$.setExpr(parser->resolveRows($1, ds), $1);
  8621. }
  8622. | XMLPROJECT '(' expression ',' transform ')'
  8623. {
  8624. parser->normalizeExpression($3, type_string, false);
  8625. parser->validateXPath($3);
  8626. $$.setExpr(createDatasetF(no_xmlproject, $3.getExpr(), $5.getExpr(), parser->createUniqueId(), NULL));
  8627. $$.setPosition($1);
  8628. }
  8629. | MAP '(' mapDatarowSpec ',' dataRow ')'
  8630. {
  8631. HqlExprArray args;
  8632. OwnedHqlExpr elseExpr = $5.getExpr();
  8633. $3.unwindCommaList(args);
  8634. parser->ensureMapToRecordsMatch(elseExpr, args, $5, true);
  8635. args.append(*elseExpr.getClear());
  8636. $$.setExpr(::createRow(no_map, args));
  8637. $$.setPosition($1);
  8638. }
  8639. | CASE '(' expression ',' beginList caseDatarowSpec ',' dataRow ')'
  8640. {
  8641. parser->normalizeExpression($3, type_scalar, false);
  8642. HqlExprArray args;
  8643. OwnedHqlExpr elseExpr = $8.getExpr();
  8644. parser->endList(args);
  8645. parser->checkCaseForDuplicates(args, $6);
  8646. parser->ensureMapToRecordsMatch(elseExpr, args, $8, true);
  8647. args.add(*$3.getExpr(),0);
  8648. args.append(*elseExpr.getClear());
  8649. $$.setExpr(::createRow(no_case, args), $1);
  8650. }
  8651. | WHEN '(' dataSet ',' action sideEffectOptions ')'
  8652. {
  8653. $$.setExpr(createDatasetF(no_executewhen, $3.getExpr(), $5.getExpr(), $6.getExpr(), NULL), $1);
  8654. }
  8655. | SUCCESS '(' dataSet ',' action ')'
  8656. {
  8657. $$.setExpr(createDatasetF(no_executewhen, $3.getExpr(), $5.getExpr(), createAttribute(successAtom), NULL), $1);
  8658. }
  8659. //Slightly unusual arrangement of the productions there to resolve s/r errors
  8660. | AGGREGATE '(' startLeftDelaySeqFilter ',' startRightRowsRecord ',' transform beginList ')' endRowsGroup endSelectorSequence
  8661. {
  8662. $$.setExpr(parser->processUserAggregate($1, $3, $5, $7, NULL, NULL, $10, $11), $1);
  8663. }
  8664. | AGGREGATE '(' startLeftDelaySeqFilter ',' startRightRowsRecord ',' transform beginList ',' sortList ')' endRowsGroup endSelectorSequence
  8665. {
  8666. $$.setExpr(parser->processUserAggregate($1, $3, $5, $7, NULL, &$10, $12, $13), $1);
  8667. }
  8668. | AGGREGATE '(' startLeftDelaySeqFilter ',' startRightRowsRecord ',' transform beginList ',' transform ')' endRowsGroup endSelectorSequence
  8669. {
  8670. $$.setExpr(parser->processUserAggregate($1, $3, $5, $7, &$10, NULL, $12, $13), $1);
  8671. }
  8672. | AGGREGATE '(' startLeftDelaySeqFilter ',' startRightRowsRecord ',' transform beginList ',' transform ',' sortList ')' endRowsGroup endSelectorSequence
  8673. {
  8674. $$.setExpr(parser->processUserAggregate($1, $3, $5, $7, &$10, &$12, $14, $15), $1);
  8675. }
  8676. /*
  8677. //This may cause s/r problems with the attribute version if a dataset name clashes with a hint id
  8678. | HINT '(' dataSet ',' hintList ')'
  8679. {
  8680. HqlExprArray hints;
  8681. $5.unwindCommaList(hints);
  8682. OwnedHqlExpr hint = createExprAttribute(hintAtom, hints);
  8683. //Add a hint attribute to the dataset
  8684. OwnedHqlExpr ds = $3.getExpr();
  8685. $$.setExpr(appendOwnedOperand(ds, hint.getClear()), $1);
  8686. //An alternative implementation is to add an annotation to the dataset, but these will then get commoned
  8687. //up, and generally I suspect hints should be treated as not commoned up. Maybe there should be a flag!
  8688. //The code generator also doesn't yet preserve annotations from multiple branches.
  8689. //$$.setExpr(createMetaAnnotation($3.getExpr(), args), $1);
  8690. }
  8691. */
  8692. ;
  8693. dataSetList
  8694. : dataSet
  8695. | dataSet ',' dataSetList
  8696. {
  8697. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  8698. $$.setPosition($1);
  8699. }
  8700. ;
  8701. mergeDataSetList
  8702. : mergeDataSetItem
  8703. | mergeDataSetList ',' mergeDataSetItem
  8704. {
  8705. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  8706. $$.setPosition($1);
  8707. }
  8708. ;
  8709. mergeDataSetItem
  8710. : dataSet
  8711. | commonAttribute
  8712. | DEDUP {
  8713. $$.setExpr(createAttribute(dedupAtom));
  8714. $$.setPosition($1);
  8715. }
  8716. | SORTED '(' startSortOrder heterogeneous_expr_list ')' endSortOrder
  8717. {
  8718. HqlExprArray args;
  8719. $4.unwindCommaList(args);
  8720. $$.setExpr(createExprAttribute(sortedAtom, args));
  8721. $$.setPosition($1);
  8722. }
  8723. ;
  8724. cogroupDataSetList
  8725. : cogroupDataSetItem
  8726. | cogroupDataSetList ',' cogroupDataSetItem
  8727. {
  8728. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  8729. $$.setPosition($1);
  8730. }
  8731. ;
  8732. cogroupDataSetItem
  8733. : dataSet
  8734. | commonAttribute
  8735. | GROUPBY '(' beginList sortList ')'
  8736. {
  8737. HqlExprArray sortItems;
  8738. parser->endList(sortItems);
  8739. IHqlExpression * sortlist = parser->processSortList($4, no_sortlist, NULL, sortItems, NULL, NULL);
  8740. $$.setExpr(createExprAttribute(groupAtom, sortlist), $1);
  8741. }
  8742. ;
  8743. sideEffectOptions
  8744. :
  8745. {
  8746. $$.setNullExpr();
  8747. }
  8748. | ',' BEFORE
  8749. {
  8750. $$.setExpr(createAttribute(beforeAtom), $2);
  8751. }
  8752. | ',' SUCCESS
  8753. {
  8754. $$.setExpr(createAttribute(successAtom), $2);
  8755. }
  8756. | ',' FAILURE
  8757. {
  8758. $$.setExpr(createAttribute(failureAtom), $2);
  8759. }
  8760. | ',' PARALLEL
  8761. {
  8762. $$.setExpr(createAttribute(parallelAtom), $2);
  8763. }
  8764. ;
  8765. limitOptions
  8766. : { $$.setNullExpr(); }
  8767. | ',' limitOption limitOptions
  8768. {
  8769. $$.setExpr(createComma($2.getExpr(), $3.getExpr()));
  8770. }
  8771. ;
  8772. limitOption
  8773. : KEYED { $$.setExpr(createAttribute(keyedAtom)); $$.setPosition($1); }
  8774. | COUNT { $$.setExpr(createAttribute(countAtom)); $$.setPosition($1); }
  8775. | SKIP { $$.setExpr(createAttribute(skipAtom)); $$.setPosition($1); }
  8776. | ONFAIL '(' transform ')'
  8777. {
  8778. $$.setExpr(createExprAttribute(onFailAtom, $3.getExpr()));
  8779. $$.setPosition($1);
  8780. }
  8781. | failAction
  8782. | commonAttribute
  8783. ;
  8784. catchOption
  8785. : SKIP { $$.setExpr(createAttribute(skipAtom)); $$.setPosition($1); }
  8786. | ONFAIL '(' transform ')'
  8787. {
  8788. $$.setExpr(createExprAttribute(onFailAtom, $3.getExpr()));
  8789. $$.setPosition($1);
  8790. }
  8791. | failAction
  8792. ;
  8793. projectOptions
  8794. : { $$.setNullExpr(); }
  8795. | projectOptions ',' projectOption
  8796. {
  8797. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  8798. }
  8799. ;
  8800. projectOption
  8801. : commonAttribute
  8802. | prefetchAttribute
  8803. | KEYED
  8804. {
  8805. $$.setExpr(createAttribute(keyedAtom));
  8806. $$.setPosition($1);
  8807. }
  8808. ;
  8809. prefetchAttribute
  8810. : PREFETCH
  8811. {
  8812. $$.setExpr(createExprAttribute(prefetchAtom));
  8813. $$.setPosition($1);
  8814. }
  8815. | PREFETCH '(' expression ')'
  8816. {
  8817. parser->normalizeExpression($3, type_int, false);
  8818. $$.setExpr(createExprAttribute(prefetchAtom, $3.getExpr()));
  8819. $$.setPosition($1);
  8820. }
  8821. | PREFETCH '(' expression ',' PARALLEL ')'
  8822. {
  8823. parser->normalizeExpression($3, type_int, false);
  8824. $$.setExpr(createExprAttribute(prefetchAtom, $3.getExpr(), createExprAttribute(parallelAtom)));
  8825. $$.setPosition($1);
  8826. }
  8827. ;
  8828. loopOptions
  8829. : {
  8830. $$.setNullExpr();
  8831. }
  8832. | loopOptions ',' loopOption
  8833. {
  8834. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  8835. }
  8836. ;
  8837. loopOption
  8838. : PARALLEL '(' expression ')'
  8839. {
  8840. parser->normalizeExpression($3); // could check more...
  8841. $$.setExpr(createExprAttribute(parallelAtom, $3.getExpr()));
  8842. $$.setPosition($1);
  8843. }
  8844. | PARALLEL '(' expression ',' expression ')'
  8845. {
  8846. parser->normalizeExpression($3, type_set, false);
  8847. parser->normalizeExpression($5, type_int, false);
  8848. $$.setExpr(createExprAttribute(parallelAtom, $3.getExpr(), $5.getExpr()));
  8849. $$.setPosition($1);
  8850. }
  8851. | commonAttribute
  8852. ;
  8853. graphOptions
  8854. : {
  8855. $$.setNullExpr();
  8856. }
  8857. | graphOptions ',' graphOption
  8858. {
  8859. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  8860. }
  8861. ;
  8862. graphOption
  8863. : PARALLEL
  8864. {
  8865. $$.setExpr(createExprAttribute(parallelAtom));
  8866. $$.setPosition($1);
  8867. }
  8868. | commonAttribute
  8869. ;
  8870. remoteOptions
  8871. :
  8872. {
  8873. $$.setNullExpr();
  8874. }
  8875. | ',' LIMIT '(' expression limitOptions ')'
  8876. {
  8877. parser->normalizeExpression($4, type_int, false);
  8878. $$.setExpr(createExprAttribute(rowLimitAtom, $4.getExpr(), $5.getExpr()));
  8879. $$.setPosition($2);
  8880. }
  8881. ;
  8882. distributedFlags
  8883. : {
  8884. $$.setNullExpr();
  8885. }
  8886. | distributedFlags ',' distributedFlag
  8887. {
  8888. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  8889. }
  8890. ;
  8891. distributedFlag
  8892. : TOK_ASSERT {
  8893. $$.setExpr(createAttribute(assertAtom));
  8894. $$.setPosition($1);
  8895. }
  8896. ;
  8897. optStepFlags
  8898. : { $$.setNullExpr(); }
  8899. | ',' stepFlag optStepFlags
  8900. {
  8901. $$.setExpr(createComma($2.getExpr(), $3.getExpr()), $2);
  8902. }
  8903. ;
  8904. stepFlag
  8905. : PRIORITY '(' expression ')'
  8906. {
  8907. parser->normalizeExpression($3, type_real, false);
  8908. $$.setExpr(createExprAttribute(priorityAtom, $3.getExpr()), $1);
  8909. }
  8910. | PREFETCH
  8911. {
  8912. $$.setExpr(createExprAttribute(prefetchAtom), $1);
  8913. }
  8914. | PREFETCH '(' expression ')'
  8915. {
  8916. parser->normalizeExpression($3, type_int, false);
  8917. $$.setExpr(createExprAttribute(prefetchAtom, $3.getExpr()), $1);
  8918. }
  8919. | FILTERED
  8920. {
  8921. $$.setExpr(createExprAttribute(filteredAtom), $1);
  8922. }
  8923. | hintAttribute
  8924. ;
  8925. sectionArguments
  8926. : { $$.setNullExpr(); }
  8927. | ',' sectionArgument sectionArguments
  8928. {
  8929. $$.setExpr(createComma($2.getExpr(), $3.getExpr()));
  8930. $$.setPosition($1);
  8931. }
  8932. ;
  8933. sectionArgument
  8934. : dataSet
  8935. | GRAPH
  8936. {
  8937. $$.setExpr(createAttribute(graphAtom), $1);
  8938. }
  8939. | PRIVATE
  8940. {
  8941. $$.setExpr(createAttribute(privateAtom), $1);
  8942. }
  8943. ;
  8944. enumDef
  8945. : enumBegin enumFirst enumValues ')'
  8946. {
  8947. $$.setExpr(parser->leaveEnum($1), $1);
  8948. }
  8949. ;
  8950. enumBegin
  8951. : ENUM '('
  8952. {
  8953. OwnedITypeInfo type = makeIntType(4, false);
  8954. parser->enterEnum($1, type);
  8955. $$.clear();
  8956. }
  8957. ;
  8958. enumFirst
  8959. : enumValue
  8960. | scalarType
  8961. {
  8962. OwnedITypeInfo type = $1.getType();
  8963. parser->setEnumType($1, type);
  8964. $$.clear();
  8965. }
  8966. ;
  8967. enumValues
  8968. :
  8969. | enumValues ',' enumValue
  8970. ;
  8971. enumValue
  8972. : UNKNOWN_ID
  8973. {
  8974. parser->processEnum($1, NULL);
  8975. $$.clear();
  8976. }
  8977. | UNKNOWN_ID EQ expression
  8978. {
  8979. parser->normalizeExpression($3, type_numeric, false);
  8980. OwnedHqlExpr nextValue = $3.getExpr();
  8981. parser->processEnum($1, nextValue);
  8982. $$.clear();
  8983. }
  8984. | SCOPE_ID
  8985. {
  8986. $1.setId(parser->getNameFromExpr($1));
  8987. parser->processEnum($1, NULL);
  8988. $$.clear();
  8989. }
  8990. | SCOPE_ID EQ expression
  8991. {
  8992. $1.setId(parser->getNameFromExpr($1));
  8993. parser->normalizeExpression($3, type_numeric, false);
  8994. OwnedHqlExpr nextValue = $3.getExpr();
  8995. parser->processEnum($1, nextValue);
  8996. $$.clear();
  8997. }
  8998. ;
  8999. indexTopRecordAndName
  9000. : optRecordDef ',' thorFilenameOrList
  9001. {
  9002. parser->normalizeExpression($3, type_string, false);
  9003. OwnedHqlExpr record = $1.getExpr();
  9004. OwnedHqlExpr name = $3.getExpr();
  9005. if (record->getOperator() == no_null)
  9006. {
  9007. if (parser->topScopes.ordinality())
  9008. record.setown(parser->createRecordFromDataset(&parser->topScopes.tos()));
  9009. else
  9010. {
  9011. parser->reportError(ERR_RECORD_EMPTYDEF, $1, "Record cannot be omitted when dataset not supplied");
  9012. record.set(queryNullRecord());
  9013. }
  9014. }
  9015. parser->pushTopScope(record);
  9016. $$.setExpr(createComma(record.getClear(), name.getClear()));
  9017. }
  9018. | optRecordDef ',' transform ',' thorFilenameOrList
  9019. {
  9020. parser->normalizeExpression($5, type_string, false);
  9021. OwnedHqlExpr record = $1.getExpr();
  9022. OwnedHqlExpr transform = $3.getExpr();
  9023. OwnedHqlExpr name = $5.getExpr();
  9024. if (record->getOperator() == no_null)
  9025. {
  9026. if (parser->topScopes.ordinality())
  9027. record.setown(parser->createRecordFromDataset(&parser->topScopes.tos()));
  9028. else
  9029. {
  9030. parser->reportError(ERR_RECORD_EMPTYDEF, $1, "Record cannot be omitted when dataset not supplied");
  9031. record.set(queryNullRecord());
  9032. }
  9033. }
  9034. parser->pushTopScope(record);
  9035. $$.setExpr(createComma(record.getClear(), transform.getClear(), name.getClear()));
  9036. }
  9037. | optRecordDef ',' nullRecordDef ',' thorFilenameOrList
  9038. {
  9039. parser->normalizeExpression($5, type_string, false);
  9040. OwnedHqlExpr record = $1.getExpr();
  9041. if (record->getOperator() == no_null)
  9042. {
  9043. parser->reportError(ERR_RECORD_EMPTYDEF, $1, "Record cannot be omitted");
  9044. record.set(queryNullRecord());
  9045. }
  9046. OwnedHqlExpr payload = $3.getExpr();
  9047. OwnedHqlExpr extra = $5.getExpr();
  9048. parser->modifyIndexPayloadRecord(record, payload, extra, $1);
  9049. parser->pushTopScope(record);
  9050. $$.setExpr(createComma(record.getClear(), extra.getClear()));
  9051. }
  9052. ;
  9053. nullRecordDef
  9054. : recordDef
  9055. | startrecord endrecord
  9056. {
  9057. $$.setExpr($2.getExpr());
  9058. }
  9059. ;
  9060. failDatasetParam
  9061. : ',' beginList expression ignoreDummyList ',' expression
  9062. {
  9063. parser->normalizeExpression($3, type_int, false);
  9064. parser->normalizeExpression($6, type_string, false);
  9065. $$.setExpr(createValue(no_fail, makeVoidType(), $3.getExpr(), $6.getExpr()));
  9066. }
  9067. | ',' beginList expression ignoreDummyList
  9068. {
  9069. parser->normalizeExpression($3, type_scalar, false);
  9070. parser->checkIntegerOrString($3);
  9071. $$.setExpr(createValue(no_fail, makeVoidType(), $3.getExpr()));
  9072. }
  9073. | ',' beginList actionlist
  9074. {
  9075. HqlExprArray actions;
  9076. parser->endList(actions);
  9077. $$.setExpr(createActionList(actions), $1);
  9078. }
  9079. ;
  9080. mode
  9081. : FLAT { $$.setExpr(createValue(no_flat)); }
  9082. | CSV { $$.setExpr(createValue(no_csv)); }
  9083. | CSV '(' csvOptions ')'
  9084. {
  9085. HqlExprArray args;
  9086. $3.unwindCommaList(args);
  9087. $$.setExpr(createValue(no_csv, makeNullType(), args));
  9088. }
  9089. | SQL { $$.setExpr(createValue(no_sql)); }
  9090. | THOR { $$.setExpr(createValue(no_thor)); }
  9091. | THOR '(' expression ')'
  9092. {
  9093. throwUnexpected();
  9094. parser->normalizeExpression($3);
  9095. $$.setExpr(createValue(no_thor, $3.getExpr()));
  9096. }
  9097. | XML_TOKEN { $$.setExpr(createValue(no_xml)); }
  9098. | XML_TOKEN '(' xmlOptions ')'
  9099. {
  9100. HqlExprArray args;
  9101. $3.unwindCommaList(args);
  9102. //Create expression in a form that is backward compatible
  9103. IHqlExpression * name = queryAttribute(rowAtom, args);
  9104. if (name)
  9105. {
  9106. args.add(*LINK(name->queryChild(0)), 0);
  9107. args.zap(*name);
  9108. }
  9109. else
  9110. args.add(*createConstant("xml"), 0);
  9111. $$.setExpr(createValue(no_xml, makeNullType(), args));
  9112. }
  9113. | pipe
  9114. ;
  9115. dsOption
  9116. : OPT { $$.setExpr(createAttribute(optAtom)); }
  9117. | UNSORTED { $$.setExpr(createAttribute(unsortedAtom)); }
  9118. | RANDOM { $$.setExpr(createAttribute(randomAtom)); }
  9119. | SEQUENTIAL { $$.setExpr(createAttribute(sequentialAtom)); }
  9120. | TOK_BITMAP { $$.setExpr(createAttribute(bitmapAtom)); }
  9121. | __COMPRESSED__ { $$.setExpr(createAttribute(__compressed__Atom)); }
  9122. | __GROUPED__ { $$.setExpr(createAttribute(groupedAtom)); }
  9123. | PRELOAD { $$.setExpr(createAttribute(preloadAtom)); }
  9124. | PRELOAD '(' constExpression ')'
  9125. { $$.setExpr(createAttribute(preloadAtom, $3.getExpr())); }
  9126. | ENCRYPT '(' expression ')'
  9127. {
  9128. parser->normalizeExpression($3, type_data, false);
  9129. $$.setExpr(createExprAttribute(encryptAtom, $3.getExpr()));
  9130. $$.setPosition($1);
  9131. }
  9132. | DYNAMIC
  9133. {
  9134. $$.setExpr(createAttribute(dynamicAtom));
  9135. $$.setPosition($1);
  9136. }
  9137. | COUNT '(' constExpression ')'
  9138. { $$.setExpr(createExprAttribute(countAtom, $3.getExpr()), $1); }
  9139. | MAXCOUNT '(' constExpression ')'
  9140. { $$.setExpr(createExprAttribute(maxCountAtom, $3.getExpr()), $1); }
  9141. | AVE '(' constExpression ')'
  9142. { $$.setExpr(createExprAttribute(aveAtom, $3.getExpr()), $1); }
  9143. | commonAttribute
  9144. ;
  9145. dsOptions
  9146. : dsOption
  9147. | dsOptions ',' dsOption
  9148. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  9149. ;
  9150. optDsOptions
  9151. : { $$.setNullExpr(); }
  9152. | ',' dsOptions { $$.setExpr($2.getExpr()); }
  9153. ;
  9154. thorFilenameOrList
  9155. : expression {
  9156. parser->convertAllToAttribute($1);
  9157. $$.inherit($1);
  9158. }
  9159. | DYNAMIC '(' expression ')'
  9160. {
  9161. parser->normalizeExpression($3, type_string, false);
  9162. $$.setExpr(createComma($3.getExpr(), createAttribute(dynamicAtom)));
  9163. $$.setPosition($1);
  9164. }
  9165. ;
  9166. indexListOpt
  9167. : { $$.setNullExpr(); }
  9168. | indexListOpt ',' dataSet
  9169. {
  9170. IHqlExpression * index = $3.getExpr();
  9171. if (!isKey(index))
  9172. parser->reportError(ERR_EXPECTED_INDEX, $3, "Expected INDEX as parameter to KEYED");
  9173. $$.setExpr(createComma($1.getExpr(), index));
  9174. }
  9175. ;
  9176. csvOptions
  9177. : csvOption
  9178. | csvOption ',' csvOptions
  9179. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  9180. ;
  9181. csvOption
  9182. : EBCDIC {
  9183. $$.setExpr(createAttribute(ebcdicAtom));
  9184. $$.setPosition($1);
  9185. }
  9186. | ASCII {
  9187. $$.setExpr(createAttribute(asciiAtom));
  9188. $$.setPosition($1);
  9189. }
  9190. | SIMPLE_TYPE {
  9191. Owned<ITypeInfo> type = $1.getType();
  9192. if (type->getTypeCode() != type_unicode && type->getTypeCode() != type_utf8)
  9193. parser->reportError(ERR_EXPECTED, $1, "Expected UNICODE");
  9194. $$.setExpr(createAttribute(unicodeAtom));
  9195. $$.setPosition($1);
  9196. }
  9197. | HEADING
  9198. {
  9199. $$.setExpr(createAttribute(headingAtom));
  9200. $$.setPosition($1);
  9201. }
  9202. | HEADING '(' startHeadingAttrs headingOptions ')'
  9203. {
  9204. HqlExprArray args;
  9205. $4.unwindCommaList(args);
  9206. HqlExprArray orderedArgs;
  9207. reorderAttributesToEnd(orderedArgs, args);
  9208. $$.setExpr(createExprAttribute(headingAtom, orderedArgs), $1);
  9209. $$.setPosition($1);
  9210. }
  9211. | MAXLENGTH '(' constExpression ')'
  9212. {
  9213. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  9214. $$.setPosition($1);
  9215. }
  9216. | MAXSIZE '(' constExpression ')'
  9217. {
  9218. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  9219. $$.setPosition($1);
  9220. }
  9221. | QUOTE '(' expression ')'
  9222. {
  9223. parser->normalizeExpression($3);
  9224. $$.setExpr(createExprAttribute(quoteAtom, $3.getExpr()));
  9225. $$.setPosition($1);
  9226. }
  9227. | SEPARATOR '(' expression ')'
  9228. {
  9229. parser->normalizeExpression($3);
  9230. $$.setExpr(createExprAttribute(separatorAtom, $3.getExpr()));
  9231. $$.setPosition($1);
  9232. }
  9233. | TERMINATOR '(' expression ')'
  9234. {
  9235. parser->normalizeExpression($3);
  9236. $$.setExpr(createExprAttribute(terminatorAtom, $3.getExpr()));
  9237. $$.setPosition($1);
  9238. }
  9239. | TERMINATOR '(' expression ',' QUOTE ')'
  9240. {
  9241. parser->normalizeExpression($3);
  9242. $$.setExpr(createExprAttribute(terminatorAtom, createComma($3.getExpr(), createAttribute(quoteAtom))));
  9243. $$.setPosition($1);
  9244. }
  9245. | ESCAPE '(' expression ')'
  9246. {
  9247. parser->normalizeExpression($3);
  9248. $$.setExpr(createExprAttribute(escapeAtom, $3.getExpr()));
  9249. $$.setPosition($1);
  9250. }
  9251. | NOTRIM
  9252. {
  9253. $$.setExpr(createAttribute(noTrimAtom));
  9254. $$.setPosition($1);
  9255. }
  9256. ;
  9257. headingOptions
  9258. : headingOption
  9259. | headingOptions ',' headingOption
  9260. {
  9261. $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1);
  9262. }
  9263. ;
  9264. headingOption
  9265. : SINGLE { $$.setExpr(createAttribute(singleAtom), $1); }
  9266. | MANY { $$.setExpr(createAttribute(manyAtom), $1); }
  9267. | expression
  9268. {
  9269. parser->normalizeExpression($1);
  9270. $$.inherit($1);
  9271. }
  9272. | FORMAT_ATTR '(' valueFunction ')'
  9273. {
  9274. //MORE: This really should check the prototype matches what we expect
  9275. $$.setExpr(createExprAttribute(formatAtom, $3.getExpr()), $1);
  9276. }
  9277. ;
  9278. xmlOptions
  9279. : xmlOption
  9280. | xmlOptions ',' xmlOption
  9281. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  9282. ;
  9283. xmlOption
  9284. : MAXLENGTH '(' constExpression ')'
  9285. {
  9286. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  9287. }
  9288. | MAXSIZE '(' constExpression ')'
  9289. {
  9290. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  9291. }
  9292. | NOROOT { $$.setExpr(createAttribute(noRootAtom)); }
  9293. | HEADING '(' expression optCommaExpression ')'
  9294. {
  9295. parser->normalizeExpression($3, type_string, false);
  9296. if ($4.queryExpr())
  9297. parser->normalizeExpression($4, type_string, false);
  9298. $$.setExpr(createExprAttribute(headingAtom, $3.getExpr(), $4.getExpr()));
  9299. $$.setPosition($1);
  9300. }
  9301. | expression {
  9302. parser->normalizeExpression($1, type_string, false);
  9303. $$.setExpr(createExprAttribute(rowAtom, $1.getExpr()));
  9304. $$.setPosition($1);
  9305. }
  9306. | TRIM {
  9307. $$.setExpr(createAttribute(trimAtom));
  9308. $$.setPosition($1);
  9309. }
  9310. | OPT {
  9311. $$.setExpr(createAttribute(optAtom));
  9312. $$.setPosition($1);
  9313. }
  9314. ;
  9315. optPipeOptions
  9316. : { $$.setNullExpr(); }
  9317. | ',' pipeOptions { $$.inherit($2); }
  9318. pipeOptions
  9319. : pipeOption
  9320. | pipeOptions ',' pipeOption
  9321. { $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1); }
  9322. ;
  9323. pipeOption
  9324. : REPEAT { $$.setExpr(createAttribute(repeatAtom)); }
  9325. | pipeFormatOption
  9326. | OUTPUT '(' pipeFormatOption ')'
  9327. {
  9328. $$.setExpr(createExprAttribute(outputAtom, $3.getExpr()), $1);
  9329. }
  9330. | GROUP { $$.setExpr(createAttribute(groupAtom)); }
  9331. | OPT { $$.setExpr(createAttribute(optAtom)); }
  9332. ;
  9333. pipeFormatOption
  9334. : CSV {
  9335. $$.setExpr(createAttribute(csvAtom), $1);
  9336. }
  9337. | CSV '(' csvOptions ')'
  9338. {
  9339. HqlExprArray args;
  9340. $3.unwindCommaList(args);
  9341. $$.setExpr(createExprAttribute(csvAtom, args), $1);
  9342. }
  9343. | XML_TOKEN {
  9344. $$.setExpr(createAttribute(xmlAtom), $1);
  9345. }
  9346. | XML_TOKEN '(' xmlOptions ')'
  9347. {
  9348. HqlExprArray args;
  9349. $3.unwindCommaList(args);
  9350. $$.setExpr(createExprAttribute(xmlAtom, args), $1);
  9351. }
  9352. | FLAT { $$.setExpr(createAttribute(flatAtom), $1); }
  9353. | THOR { $$.setExpr(createAttribute(thorAtom), $1); }
  9354. ;
  9355. setCountList
  9356. : mapSpec
  9357. | mapSpec ',' expression
  9358. {
  9359. parser->normalizeExpression($3, type_int, false);
  9360. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  9361. }
  9362. | mapSpec ',' choosesetAttr
  9363. {
  9364. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  9365. }
  9366. | mapSpec ',' expression ',' choosesetAttr
  9367. {
  9368. parser->normalizeExpression($3, type_int, false);
  9369. $$.setExpr(createComma($1.getExpr(), createComma($3.getExpr(), $5.getExpr())));
  9370. }
  9371. ;
  9372. choosesetAttr
  9373. : EXCLUSIVE { $$.setExpr(createAttribute(exclusiveAtom)); }
  9374. | ENTH { $$.setExpr(createAttribute(enthAtom)); }
  9375. | LAST { $$.setExpr(createAttribute(lastAtom)); }
  9376. ;
  9377. pipe
  9378. : PIPE '(' expression optPipeOptions ')'
  9379. {
  9380. parser->normalizeExpression($3, type_string, false);
  9381. $$.setExpr(createComma(createValue(no_pipe, makeNullType(), $3.getExpr()), $4.getExpr()));
  9382. }
  9383. ;
  9384. choosenExtra
  9385. : {
  9386. $$.setNullExpr();
  9387. }
  9388. | ',' choosenFlags
  9389. {
  9390. $$.inherit($2);
  9391. }
  9392. | ',' expression
  9393. {
  9394. parser->normalizeExpression($2, type_int, false);
  9395. $$.inherit($2);
  9396. }
  9397. | ',' expression ',' choosenFlags
  9398. {
  9399. parser->normalizeExpression($2, type_int, false);
  9400. $$.setExpr(createComma($2.getExpr(), $4.getExpr()));
  9401. $$.setPosition($2);
  9402. }
  9403. ;
  9404. choosenFlags
  9405. : choosenFlag
  9406. | choosenFlags ',' choosenFlag
  9407. {
  9408. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  9409. $$.setPosition($1);
  9410. }
  9411. ;
  9412. choosenFlag
  9413. : GROUPED
  9414. {
  9415. $$.setExpr(createAttribute(groupedAtom));
  9416. $$.setPosition($1);
  9417. }
  9418. | commonAttribute
  9419. | FEW
  9420. {
  9421. $$.setExpr(createAttribute(fewAtom));
  9422. $$.setPosition($1);
  9423. }
  9424. ;
  9425. inlineFieldValue2
  9426. : expression
  9427. {
  9428. parser->normalizeExpression($1);
  9429. $$.inherit($1);
  9430. }
  9431. | dataSet
  9432. | inlineDatasetValue
  9433. | dataRow
  9434. | '[' beginList inlineDatasetValueList ']'
  9435. {
  9436. HqlExprArray values;
  9437. parser->endList(values);
  9438. $$.setExpr(createValue(no_recordlist, makeNullType(), values));
  9439. }
  9440. ;
  9441. inlineFieldValue
  9442. : inlineFieldValue2 {
  9443. parser->addListElement($1.getExpr());
  9444. $$.clear();
  9445. }
  9446. ;
  9447. inlineFieldValueGoesTo
  9448. : GOESTO {
  9449. parser->addListElement(createAttribute(_payload_Atom));
  9450. $$.clear();
  9451. $$.setPosition($1);
  9452. }
  9453. ;
  9454. inlineFieldValues
  9455. : inlineFieldValue
  9456. | inlineFieldValues ';' inlineFieldValue
  9457. | inlineFieldValues ',' inlineFieldValue
  9458. ;
  9459. inlineFieldValuesWithGoesto
  9460. : inlineFieldValues optSemiComma
  9461. | inlineFieldValues inlineFieldValueGoesTo inlineFieldValues optSemiComma
  9462. ;
  9463. inlineDatasetValue
  9464. : '{' beginList inlineFieldValuesWithGoesto '}'
  9465. {
  9466. HqlExprArray args;
  9467. parser->endList(args);
  9468. setPayloadAttribute(args);
  9469. // args.append(*createLocationAttr($1)); // improves the error reporting, but slows it down, and changes the expression crcs
  9470. $$.setExpr(createValue(no_rowvalue, makeNullType(), args));
  9471. }
  9472. ;
  9473. inlineDatasetValueList
  9474. : inlineDatasetValue
  9475. { parser->addListElement($1.getExpr()); $$.clear(); }
  9476. | simpleRecord
  9477. { parser->addListElement($1.getExpr()); $$.clear(); }
  9478. | inlineDatasetValueList ',' inlineDatasetValue
  9479. { parser->addListElement($3.getExpr()); $$.clear(); }
  9480. | inlineDatasetValueList ',' simpleRecord
  9481. { parser->addListElement($3.getExpr()); $$.clear(); }
  9482. ;
  9483. transformList
  9484. : transform
  9485. {
  9486. parser->addListElement($1.getExpr());
  9487. $$.clear();
  9488. }
  9489. | transformList ',' transform
  9490. {
  9491. parser->addListElement($3.getExpr());
  9492. $$.clear();
  9493. }
  9494. ;
  9495. optJoinFlags
  9496. : { $$.setNullExpr(); }
  9497. | ',' JoinFlags { $$.setExpr($2.getExpr()); }
  9498. ;
  9499. JoinFlags
  9500. : JoinFlag
  9501. | JoinFlags ',' JoinFlag
  9502. { $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $1); }
  9503. ;
  9504. JoinFlag
  9505. : LEFT OUTER { $$.setExpr(createAttribute(leftouterAtom)); $$.setPosition($1); }
  9506. | RIGHT OUTER { $$.setExpr(createAttribute(rightouterAtom)); $$.setPosition($1); }
  9507. | LEFT RIGHT OUTER { $$.setExpr(createAttribute(fullouterAtom)); $$.setPosition($1); }
  9508. | FULL OUTER { $$.setExpr(createAttribute(fullouterAtom)); $$.setPosition($1); }
  9509. | LEFT ONLY { $$.setExpr(createAttribute(leftonlyAtom)); $$.setPosition($1); }
  9510. | ONLY LEFT { $$.setExpr(createAttribute(leftonlyAtom)); $$.setPosition($1); }
  9511. | RIGHT ONLY { $$.setExpr(createAttribute(rightonlyAtom)); $$.setPosition($1); }
  9512. | ONLY RIGHT { $$.setExpr(createAttribute(rightonlyAtom)); $$.setPosition($1); }
  9513. | LEFT RIGHT ONLY { $$.setExpr(createAttribute(fullonlyAtom)); $$.setPosition($1); }
  9514. | FULL ONLY { $$.setExpr(createAttribute(fullonlyAtom)); $$.setPosition($1); }
  9515. | INNER { $$.setExpr(createAttribute(innerAtom)); $$.setPosition($1); }
  9516. | HASH {
  9517. $$.setExpr(createAttribute(hashAtom));
  9518. $$.setPosition($1);
  9519. }
  9520. | KEYED '(' dataSet ')'
  9521. {
  9522. IHqlExpression * index = $3.getExpr();
  9523. if (!isKey(index))
  9524. parser->reportError(ERR_EXPECTED_INDEX, $3, "Expected INDEX as parameter to KEYED");
  9525. $$.setExpr(createExprAttribute(keyedAtom, index));
  9526. $$.setPosition($1);
  9527. }
  9528. | KEYED
  9529. {
  9530. $$.setExpr(createAttribute(keyedAtom));
  9531. $$.setPosition($1);
  9532. }
  9533. | FEW
  9534. {
  9535. $$.setExpr(createAttribute(fewAtom));
  9536. $$.setPosition($1);
  9537. }
  9538. | commonAttribute
  9539. | MANY LOOKUP { $$.setExpr(createComma(createAttribute(lookupAtom), createAttribute(manyAtom))); $$.setPosition($1); }
  9540. | GROUPED { $$.setExpr(createComma(createAttribute(lookupAtom), createAttribute(manyAtom), createAttribute(groupedAtom))); $$.setPosition($1); }
  9541. | MANY { $$.setExpr(createAttribute(manyAtom)); $$.setPosition($1); }
  9542. | LOOKUP { $$.setExpr(createAttribute(lookupAtom)); $$.setPosition($1); }
  9543. | SMART { $$.setExpr(createAttribute(smartAtom)); $$.setPosition($1); }
  9544. | NOSORT { $$.setExpr(createAttribute(noSortAtom)); $$.setPosition($1); }
  9545. | NOSORT '(' LEFT ')'
  9546. { $$.setExpr(createAttribute(noSortAtom, createAttribute(leftAtom))); $$.setPosition($1); }
  9547. | NOSORT '(' RIGHT ')'
  9548. { $$.setExpr(createAttribute(noSortAtom, createAttribute(rightAtom))); $$.setPosition($1); }
  9549. | ATMOST '(' expression ')'
  9550. {
  9551. parser->normalizeExpression($3, type_numeric, false);
  9552. if ($3.isZero())
  9553. parser->reportError(ERR_BAD_JOINFLAG, $3, "ATMOST(0) doesn't make any sense");
  9554. $$.setExpr(createExprAttribute(atmostAtom, $3.getExpr()));
  9555. $$.setPosition($1);
  9556. }
  9557. | ATMOST '(' expression ',' expression ')'
  9558. {
  9559. parser->normalizeExpression($3, type_boolean, false);
  9560. parser->normalizeExpression($5, type_numeric, false);
  9561. if ($5.isZero())
  9562. parser->reportError(ERR_BAD_JOINFLAG, $5, "ATMOST(0) doesn't make any sense");
  9563. $$.setExpr(createExprAttribute(atmostAtom, $3.getExpr(), $5.getExpr()));
  9564. $$.setPosition($1);
  9565. }
  9566. | ATMOST '(' expression ',' sortListExpr ',' expression ')'
  9567. {
  9568. parser->normalizeExpression($3, type_boolean, false);
  9569. parser->normalizeExpression($7, type_numeric, false);
  9570. if ($7.isZero())
  9571. parser->reportError(ERR_BAD_JOINFLAG, $7, "ATMOST(0) doesn't make any sense");
  9572. $$.setExpr(createExprAttribute(atmostAtom, $3.getExpr(), $5.getExpr(), $7.getExpr()));
  9573. $$.setPosition($1);
  9574. }
  9575. | ATMOST '(' sortListExpr ',' expression ')'
  9576. {
  9577. parser->normalizeExpression($5, type_numeric, false);
  9578. if ($5.isZero())
  9579. parser->reportError(ERR_BAD_JOINFLAG, $5, "ATMOST(0) doesn't make any sense");
  9580. $$.setExpr(createExprAttribute(atmostAtom, $3.getExpr(), $5.getExpr()));
  9581. $$.setPosition($1);
  9582. }
  9583. | KEEP '(' expression ')'
  9584. {
  9585. parser->normalizeExpression($3, type_numeric, false);
  9586. $$.setExpr(createExprAttribute(keepAtom, $3.getExpr()));
  9587. $$.setPosition($1);
  9588. }
  9589. | PARTITION LEFT
  9590. {
  9591. $$.setExpr(createAttribute(partitionLeftAtom));
  9592. $$.setPosition($1);
  9593. }
  9594. | PARTITION RIGHT
  9595. {
  9596. $$.setExpr(createAttribute(partitionRightAtom));
  9597. $$.setPosition($1);
  9598. }
  9599. | THRESHOLD '(' expression ')'
  9600. {
  9601. parser->normalizeExpression($3, type_numeric, true);
  9602. $$.setExpr(createAttribute(thresholdAtom, $3.getExpr()));
  9603. $$.setPosition($1);
  9604. }
  9605. | ALL { $$.setExpr(createAttribute(allAtom)); }
  9606. | skewAttribute
  9607. | LIMIT '(' expression joinLimitOptions ')'
  9608. {
  9609. parser->normalizeExpression($3, type_numeric, false);
  9610. HqlExprArray args;
  9611. args.append(*$3.getExpr());
  9612. $4.unwindCommaList(args);
  9613. IHqlExpression * onFail = queryAttribute(onFailAtom, args);
  9614. if (onFail)
  9615. {
  9616. onFail->Link();
  9617. args.zap(*onFail);
  9618. }
  9619. IHqlExpression * attr = createExprAttribute(rowLimitAtom, args);
  9620. $$.setExpr(createComma(attr, onFail));
  9621. $$.setPosition($1);
  9622. }
  9623. | onFailAction
  9624. | PARALLEL
  9625. {
  9626. $$.setExpr(createAttribute(parallelAtom));
  9627. $$.setPosition($1);
  9628. }
  9629. | SEQUENTIAL
  9630. {
  9631. $$.setExpr(createAttribute(sequentialAtom));
  9632. $$.setPosition($1);
  9633. }
  9634. | UNORDERED
  9635. {
  9636. $$.setExpr(createAttribute(unorderedAtom));
  9637. $$.setPosition($1);
  9638. }
  9639. | GROUP '(' startSortOrder heterogeneous_expr_list ')' endSortOrder
  9640. {
  9641. HqlExprArray args;
  9642. $4.unwindCommaList(args);
  9643. OwnedHqlExpr sortlist = createSortList(args);
  9644. OwnedHqlExpr groupAttr = createExprAttribute(groupAtom, sortlist.getClear());
  9645. OwnedHqlExpr impliedAttr = createComma(createAttribute(lookupAtom), createAttribute(manyAtom));
  9646. $$.setExpr(createComma(groupAttr.getClear(), impliedAttr.getClear()), $1);
  9647. }
  9648. | STABLE
  9649. {
  9650. $$.setExpr(createExprAttribute(stableAtom));
  9651. $$.setPosition($1);
  9652. }
  9653. | UNSTABLE
  9654. {
  9655. $$.setExpr(createExprAttribute(unstableAtom));
  9656. $$.setPosition($1);
  9657. }
  9658. ;
  9659. joinLimitOptions
  9660. : { $$.setNullExpr(); }
  9661. | joinLimitOptions ',' joinLimitOption
  9662. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  9663. ;
  9664. joinLimitOption
  9665. : SKIP { $$.setExpr(createAttribute(skipAtom)); }
  9666. | COUNT { $$.setExpr(createAttribute(countAtom)); }
  9667. | failAction
  9668. | transform
  9669. {
  9670. $$.setExpr(createExprAttribute(onFailAtom, $1.getExpr()));
  9671. $$.setPosition($1);
  9672. }
  9673. ;
  9674. mergeJoinFlags
  9675. : mergeJoinFlag
  9676. | mergeJoinFlags ',' mergeJoinFlag
  9677. {
  9678. $$.setExpr(createComma($1.getExpr(), $3.getExpr()));
  9679. $$.setPosition($1);
  9680. }
  9681. ;
  9682. mergeJoinFlag
  9683. : MOFN '(' expression ')'
  9684. {
  9685. parser->normalizeExpression($3, type_numeric, false);
  9686. $$.setExpr(createExprAttribute(mofnAtom, $3.getExpr()));
  9687. $$.setPosition($1);
  9688. }
  9689. | MOFN '(' expression ',' expression ')'
  9690. {
  9691. parser->normalizeExpression($3, type_numeric, false);
  9692. parser->normalizeExpression($5, type_numeric, false);
  9693. $$.setExpr(createExprAttribute(mofnAtom, $3.getExpr(), $5.getExpr()));
  9694. $$.setPosition($1);
  9695. }
  9696. | DEDUP
  9697. {
  9698. $$.setExpr(createAttribute(dedupAtom));
  9699. $$.setPosition($1);
  9700. }
  9701. | LEFT ONLY
  9702. {
  9703. $$.setExpr(createAttribute(leftonlyAtom));
  9704. $$.setPosition($1);
  9705. }
  9706. | LEFT OUTER
  9707. {
  9708. $$.setExpr(createAttribute(leftouterAtom));
  9709. $$.setPosition($1);
  9710. }
  9711. | TOK_ASSERT SORTED
  9712. {
  9713. $$.setExpr(createAttribute(assertAtom));
  9714. $$.setPosition($1);
  9715. }
  9716. | SORTED '(' startSortOrder heterogeneous_expr_list ')' endSortOrder
  9717. {
  9718. HqlExprArray args;
  9719. $4.unwindCommaList(args);
  9720. $$.setExpr(createExprAttribute(sortedAtom, args));
  9721. $$.setPosition($1);
  9722. }
  9723. | INTERNAL '(' constExpression ')'
  9724. {
  9725. parser->normalizeExpression($3, type_int, false);
  9726. $$.setExpr(createExprAttribute(internalFlagsAtom, $3.getExpr()));
  9727. $$.setPosition($1);
  9728. }
  9729. | PARTITION '(' heterogeneous_expr_list ')'
  9730. {
  9731. HqlExprArray args;
  9732. $3.unwindCommaList(args);
  9733. $$.setExpr(createExprAttribute(skewAtom, args));
  9734. $$.setPosition($1);
  9735. }
  9736. | commonAttribute
  9737. ;
  9738. skewAttribute
  9739. : SKEW '(' expression ')'
  9740. {
  9741. parser->normalizeExpression($3, type_numeric, true);
  9742. $$.setExpr(createAttribute(skewAtom, $3.getExpr()));
  9743. }
  9744. | SKEW '(' optExpression ',' expression ')'
  9745. {
  9746. if ($3.queryExpr())
  9747. {
  9748. parser->normalizeExpression($3, type_numeric, true);
  9749. }
  9750. else
  9751. $3.setExpr(createValue(no_null));
  9752. parser->normalizeExpression($5, type_any, true);
  9753. parser->normalizeExpression($5, type_numeric, false);
  9754. $$.setExpr(createAttribute(skewAtom, $3.getExpr(), $5.getExpr()));
  9755. }
  9756. ;
  9757. optDistributionFlags
  9758. : { $$.setNullExpr(); }
  9759. | ',' DistributionFlags
  9760. {
  9761. $$.setExpr($2.getExpr());
  9762. $$.setPosition($1);
  9763. }
  9764. ;
  9765. DistributionFlags
  9766. : DistributionFlag
  9767. | DistributionFlags ',' DistributionFlag { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  9768. ;
  9769. DistributionFlag
  9770. : ATMOST '(' expression ')'
  9771. {
  9772. parser->normalizeExpression($3, type_numeric, true);
  9773. $$.setExpr(createAttribute(atmostAtom, $3.getExpr()));
  9774. }
  9775. | SKEW
  9776. {
  9777. $$.setExpr(createAttribute(skewAtom));
  9778. }
  9779. | NAMED '(' constExpression ')'
  9780. {
  9781. parser->normalizeStoredNameExpression($3);
  9782. $$.setExpr(createAttribute(namedAtom, $3.getExpr()));
  9783. $$.setPosition($1);
  9784. }
  9785. // | commonAttribute
  9786. ;
  9787. optTrimFlags
  9788. : { $$.setNullExpr(); }
  9789. | TrimFlags
  9790. ;
  9791. TrimFlags
  9792. : commaTrimFlag
  9793. | TrimFlags commaTrimFlag
  9794. { $$.setExpr(createComma($1.getExpr(), $2.getExpr())); }
  9795. ;
  9796. commaTrimFlag
  9797. : ',' TrimFlag { $$.setExpr($2.getExpr()); }
  9798. ;
  9799. TrimFlag
  9800. : LEFT { $$.setExpr(createAttribute(leftAtom)); }
  9801. | RIGHT { $$.setExpr(createAttribute(rightAtom)); }
  9802. | ALL { $$.setExpr(createAttribute(allAtom)); }
  9803. ;
  9804. optSortList
  9805. : { $$.clear(); }
  9806. | ',' sortList
  9807. ;
  9808. doParseFlags
  9809. : parseFlags
  9810. ;
  9811. parseFlags
  9812. : { $$.setNullExpr(); }
  9813. | parseFlags ',' parseFlag
  9814. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  9815. ;
  9816. parseFlag
  9817. : ALL { $$.setExpr(createAttribute(allAtom)); }
  9818. | FIRST { $$.setExpr(createAttribute(firstAtom)); }
  9819. | WHOLE { $$.setExpr(createAttribute(wholeAtom)); }
  9820. | NOSCAN { $$.setExpr(createAttribute(noScanAtom)); }
  9821. | SCAN { $$.setExpr(createAttribute(scanAtom)); }
  9822. | SCAN ALL { $$.setExpr(createAttribute(scanAllAtom)); }
  9823. | NOCASE { $$.setExpr(createAttribute(noCaseAtom)); }
  9824. | CASE { $$.setExpr(createAttribute(caseAtom)); }
  9825. | SKIP '(' pattern ')'
  9826. { $$.setExpr(createAttribute(separatorAtom, $3.getExpr())); }
  9827. | TERMINATOR '(' expression ')'
  9828. {
  9829. parser->normalizeExpression($3, type_set, true);
  9830. parser->validateParseTerminate($3.queryExpr(), $3);
  9831. $$.setExpr(createAttribute(terminatorAtom, $3.getExpr()));
  9832. }
  9833. | ATMOST '(' constExpression ')'
  9834. {
  9835. parser->normalizeExpression($3, type_numeric, false);
  9836. $$.setExpr(createAttribute(atmostAtom, $3.getExpr()));
  9837. }
  9838. | KEEP '(' constExpression ')'
  9839. {
  9840. parser->normalizeExpression($3, type_numeric, false);
  9841. $$.setExpr(createAttribute(keepAtom, $3.getExpr()));
  9842. }
  9843. | MATCHED '(' ALL ')'
  9844. {
  9845. $$.setExpr(createValue(no_matched, makeNullType(), createValue(no_all, makeVoidType())));
  9846. }
  9847. | MATCHED '(' patternOrRuleId ')'
  9848. {
  9849. $$.setExpr(createValue(no_matched, makeNullType(), $3.getExpr()));
  9850. }
  9851. | MAX { $$.setExpr(createAttribute(maxAtom)); }
  9852. | MIN { $$.setExpr(createAttribute(minAtom)); }
  9853. | USE '(' globalPatternAttribute ')'
  9854. {
  9855. $$.setExpr(createValue(no_pat_use, $3.getExpr()));
  9856. }
  9857. | BEST { $$.setExpr(createAttribute(bestAtom)); }
  9858. | MANY BEST { $$.setExpr(createComma(createAttribute(bestAtom), createAttribute(manyAtom))); }
  9859. | MANY MIN { $$.setExpr(createComma(createAttribute(minAtom), createAttribute(manyAtom))); }
  9860. | MANY MAX { $$.setExpr(createComma(createAttribute(maxAtom), createAttribute(manyAtom))); }
  9861. | NOT MATCHED { $$.setExpr(createAttribute(notMatchedAtom)); }
  9862. | NOT MATCHED ONLY
  9863. { $$.setExpr(createAttribute(notMatchedOnlyAtom)); }
  9864. | PARSE { $$.setExpr(createAttribute(tomitaAtom)); }
  9865. | GROUP { $$.setExpr(createAttribute(groupAtom)); }
  9866. | MANY { $$.setExpr(createAttribute(manyAtom)); }
  9867. | MAXLENGTH '(' constExpression ')'
  9868. {
  9869. parser->normalizeExpression($3, type_numeric, false);
  9870. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  9871. }
  9872. | MAXSIZE '(' constExpression ')'
  9873. {
  9874. parser->normalizeExpression($3, type_numeric, false);
  9875. $$.setExpr(createExprAttribute(maxLengthAtom, $3.getExpr()));
  9876. }
  9877. | PARALLEL
  9878. {
  9879. $$.setExpr(createAttribute(parallelAtom));
  9880. $$.setPosition($1);
  9881. }
  9882. | hintAttribute
  9883. ;
  9884. xmlParseFlags
  9885. : { $$.setNullExpr(); }
  9886. | xmlParseFlags ',' xmlParseFlag
  9887. { $$.setExpr(createComma($1.getExpr(), $3.getExpr())); }
  9888. ;
  9889. xmlParseFlag
  9890. : XML_TOKEN { $$.setExpr(createAttribute(xmlAtom)); }
  9891. | XML_TOKEN '(' constExpression ')'
  9892. {
  9893. parser->normalizeExpression($3, type_string, false);
  9894. $$.setExpr(createAttribute(xmlAtom, $3.getExpr()));
  9895. }
  9896. ;
  9897. startGROUP
  9898. : ',' {
  9899. $$.clear();
  9900. }
  9901. ;
  9902. endGROUP
  9903. : ')' { parser->popTopScope(); $$.clear(); }
  9904. ;
  9905. startSortOrder
  9906. : {
  9907. parser->sortDepth++;
  9908. $$.clear();
  9909. }
  9910. ;
  9911. endSortOrder
  9912. : { parser->sortDepth--; $$.clear(); }
  9913. ;
  9914. startTopFilter
  9915. : dataSet { parser->pushTopScope($1.queryExpr()); $$.setExpr($1.getExpr()); }
  9916. ;
  9917. startRightFilter
  9918. : dataSet { parser->setRightScope($1.queryExpr()); $$.inherit($1); }
  9919. ;
  9920. startRightRowsRecord
  9921. : recordDef
  9922. {
  9923. parser->setRightScope($1.queryExpr());
  9924. parser->beginRowsScope(no_right);
  9925. $$.inherit($1);
  9926. }
  9927. ;
  9928. startLeftRightSeqFilter
  9929. : dataSet
  9930. {
  9931. parser->pushLeftRightScope($1.queryExpr(), NULL); // selector only depends on left
  9932. parser->setRightScope($1.queryExpr());
  9933. $$.inherit($1);
  9934. }
  9935. ;
  9936. startTopLeftSeqFilter
  9937. : dataSet
  9938. {
  9939. parser->pushTopScope($1.queryExpr());
  9940. parser->pushLeftRightScope($1.queryExpr(), NULL);
  9941. $$.inherit($1);
  9942. }
  9943. ;
  9944. startTopLeftRightSeqFilter
  9945. : dataSet
  9946. {
  9947. parser->pushTopScope($1.queryExpr());
  9948. parser->pushLeftRightScope($1.queryExpr(), NULL); // selector only depends on left
  9949. parser->setRightScope($1.queryExpr());
  9950. $$.inherit($1);
  9951. }
  9952. ;
  9953. startTopLeftRightSeqSetDatasets
  9954. : setOfDatasets
  9955. {
  9956. parser->pushLeftRightScope($1.queryExpr(), NULL); // selector only depends on left
  9957. parser->setRightScope($1.queryExpr());
  9958. OwnedHqlExpr pseudoTop = parser->getSelector($1, no_left);
  9959. parser->pushTopScope(pseudoTop);
  9960. $$.inherit($1);
  9961. }
  9962. ;
  9963. startPointerToMember
  9964. :
  9965. {
  9966. parser->pushTopScope(queryNullRecord());
  9967. }
  9968. LT
  9969. {
  9970. $$.inherit($2);
  9971. }
  9972. ;
  9973. endPointerToMember
  9974. :
  9975. {
  9976. parser->popTopScope();
  9977. }
  9978. GT
  9979. {
  9980. $$.inherit($2);
  9981. }
  9982. ;
  9983. startSimpleFilter
  9984. : simpleDataSet { parser->pushTopScope($1.queryExpr()); $$.setExpr($1.getExpr()); }
  9985. ;
  9986. startLeftSeqRow
  9987. : dataRow
  9988. {
  9989. parser->pushLeftRightScope($1.queryExpr(), NULL);
  9990. $$.inherit($1);
  9991. }
  9992. ;
  9993. startRightRow
  9994. : dataRow {
  9995. parser->setRightScope($1.queryExpr());
  9996. $$.setExpr($1.getExpr());
  9997. }
  9998. ;
  9999. startLeftRowsSeqFilter
  10000. : dataSet
  10001. {
  10002. parser->pushLeftRightScope($1.queryExpr(), NULL);
  10003. parser->beginRowsScope(no_left);
  10004. $$.inherit($1);
  10005. }
  10006. ;
  10007. startLeftSeqFilter
  10008. : dataSet
  10009. {
  10010. parser->pushLeftRightScope($1.queryExpr(), NULL);
  10011. $$.inherit($1);
  10012. }
  10013. ;
  10014. startLeftDelaySeqFilter
  10015. : dataSet
  10016. {
  10017. //Since the SEQUENCE is based on left and right left and right aren't valid until we have seen both datasets
  10018. parser->pushPendingLeftRightScope($1.queryExpr(), NULL);
  10019. $$.inherit($1);
  10020. }
  10021. ;
  10022. //Used for the RHS of a distribute. Top filter has already been processed, so selector id should be based on both.
  10023. startRightDistributeSeqFilter
  10024. : dataSet
  10025. {
  10026. parser->pushLeftRightScope(parser->queryTopScope(), $1.queryExpr());
  10027. $$.inherit($1);
  10028. }
  10029. ;
  10030. endSelectorSequence
  10031. : {
  10032. $$.setExpr(parser->popLeftRightScope());
  10033. }
  10034. ;
  10035. startLeftRowsGroup
  10036. : GROUP {
  10037. parser->beginRowsScope(no_left);
  10038. $$.clear();
  10039. }
  10040. ;
  10041. startLeftRows
  10042. : {
  10043. parser->beginRowsScope(no_left);
  10044. $$.clear();
  10045. }
  10046. ;
  10047. startRightRowsGroup
  10048. : GROUP {
  10049. parser->beginRowsScope(no_right);
  10050. $$.clear();
  10051. }
  10052. ;
  10053. endRowsGroup
  10054. : { $$.setExpr(parser->endRowsScope()); }
  10055. ;
  10056. endSimpleFilter
  10057. : { parser->popTopScope(); $$.clear(); }
  10058. ;
  10059. endTopFilter
  10060. : { parser->popTopScope(); $$.clear(); }
  10061. ;
  10062. endTopLeftFilter
  10063. : { parser->popTopScope(); $$.clear(); }
  10064. ;
  10065. endTopLeftRightFilter
  10066. : { parser->popTopScope(); $$.clear(); }
  10067. ;
  10068. scopedDatasetId
  10069. : globalScopedDatasetId
  10070. | dotScope DATASET_ID leaveScope
  10071. {
  10072. IHqlExpression *e1 = $1.getExpr();
  10073. IHqlExpression *e2 = $2.getExpr();
  10074. if (e1 && (e1->getOperator() != no_record) && (e2->getOperator() == no_field))
  10075. $$.setExpr(parser->createSelect(e1, e2, $2));
  10076. else
  10077. {
  10078. ::Release(e1);
  10079. $$.setExpr(e2);
  10080. }
  10081. }
  10082. | datasetFunction '('
  10083. {
  10084. parser->beginFunctionCall($1);
  10085. }
  10086. actualParameters ')'
  10087. {
  10088. $$.setExpr(parser->bindParameters($1, $4.getExpr()));
  10089. }
  10090. ;
  10091. globalScopedDatasetId
  10092. : DATASET_ID
  10093. | moduleScopeDot DATASET_ID leaveScope
  10094. {
  10095. OwnedHqlExpr scope = $1.getExpr();
  10096. $$.setExpr($2.getExpr());
  10097. }
  10098. ;
  10099. setOfDatasets
  10100. : scopedListDatasetId
  10101. | RANGE '(' setOfDatasets ',' expression ')'
  10102. {
  10103. parser->normalizeExpression($5, type_set, false);
  10104. ITypeInfo * childType = $5.queryExprType()->queryChildType();
  10105. if (!childType || !isIntegralType(childType))
  10106. parser->reportError(ERR_TYPEMISMATCH_INTREAL, $4, "Type mismatch - expected a list of integral type");
  10107. OwnedHqlExpr list = $3.getExpr();
  10108. $$.setExpr(createValue(no_rowsetrange, list->getType(), LINK(list), $5.getExpr()));
  10109. $$.setPosition($1);
  10110. }
  10111. | '[' beginList dataSetList ignoreDummyList ']'
  10112. {
  10113. HqlExprArray args;
  10114. $3.unwindCommaList(args);
  10115. parser->checkRecordsMatch($1, args);
  10116. //check all the datasets have the same record structure at a minimum.
  10117. ITypeInfo * setType = makeSetType(args.item(0).getType());
  10118. $$.setExpr(createValue(no_datasetlist, setType, args)); // This should probably be a pseudo-dataset
  10119. $$.setPosition($1);
  10120. }
  10121. | ROWSET '(' dataRow ')'
  10122. {
  10123. $$.setExpr(parser->processRowset($3), $1);
  10124. }
  10125. | startCompoundExpression beginInlineFunctionToken optDefinitions RETURN setOfDatasets ';' endInlineFunctionToken
  10126. {
  10127. Owned<ITypeInfo> retType = $1.getType();
  10128. $$.setExpr(parser->leaveLamdaExpression($5), $7);
  10129. }
  10130. ;
  10131. scopedListDatasetId
  10132. : LIST_DATASET_ID
  10133. | dotScope LIST_DATASET_ID leaveScope
  10134. {
  10135. IHqlExpression *e1 = $1.getExpr();
  10136. IHqlExpression *e2 = $2.getExpr();
  10137. if (e1 && (e1->getOperator() != no_record) && (e2->getOperator() == no_field))
  10138. $$.setExpr(parser->createSelect(e1, e2, $2));
  10139. else
  10140. {
  10141. ::Release(e1);
  10142. $$.setExpr(e2);
  10143. }
  10144. }
  10145. | moduleScopeDot LIST_DATASET_ID leaveScope
  10146. {
  10147. OwnedHqlExpr scope = $1.getExpr();
  10148. $$.setExpr($2.getExpr());
  10149. }
  10150. | listDatasetFunction '('
  10151. {
  10152. parser->beginFunctionCall($1);
  10153. }
  10154. actualParameters ')'
  10155. {
  10156. $$.setExpr(parser->bindParameters($1, $4.getExpr()));
  10157. }
  10158. ;
  10159. actualParameters
  10160. : actualList { $$.setExpr(parser->endFunctionCall(), $1); }
  10161. ;
  10162. actualList
  10163. : optActualValue
  10164. | actualList ',' optActualValue
  10165. ;
  10166. optActualValue
  10167. : {
  10168. parser->addActual($$, createOmittedValue());
  10169. $$.clear();
  10170. }
  10171. | actualValue {
  10172. parser->addActual($1, $1.getExpr());
  10173. $$.clear();
  10174. }
  10175. | namedActual
  10176. ;
  10177. namedActual
  10178. : UNKNOWN_ID ASSIGN actualValue
  10179. {
  10180. parser->addNamedActual($1, $1.getId(), $3.getExpr());
  10181. $$.clear();
  10182. $$.setPosition($1);
  10183. }
  10184. | NAMED UNKNOWN_ID ASSIGN actualValue
  10185. {
  10186. parser->addNamedActual($1, $2.getId(), $4.getExpr());
  10187. $$.clear();
  10188. $$.setPosition($1);
  10189. }
  10190. | goodObject ASSIGN actualValue
  10191. {
  10192. OwnedHqlExpr nameExpr = $1.getExpr();
  10193. IIdAtom * name = nameExpr->queryId();
  10194. if (!name)
  10195. {
  10196. name = unknownId;
  10197. parser->reportError(ERR_EXPECTED_ID, $1, "Expected a parameter name");
  10198. }
  10199. parser->addNamedActual($1, name, $3.getExpr());
  10200. $$.clear();
  10201. $$.setPosition($1);
  10202. }
  10203. ;
  10204. actualValue
  10205. : expression
  10206. {
  10207. parser->normalizeExpression($1);
  10208. $$.inherit($1);
  10209. }
  10210. | dataSet optFieldMaps
  10211. {
  10212. IHqlExpression* expr = $1.getExpr();
  10213. IHqlExpression* map = $2.getExpr();
  10214. $$.setExpr(parser->bindFieldMap(expr,map));
  10215. }
  10216. | dataRow
  10217. | dictionary
  10218. | TOK_PATTERN pattern
  10219. { $$.setExpr($2.getExpr()); }
  10220. | TOKEN pattern { $$.setExpr($2.getExpr()); }
  10221. | RULE pattern { $$.setExpr($2.getExpr()); }
  10222. | anyFunction
  10223. | abstractModule
  10224. | setOfDatasets
  10225. | recordDef
  10226. | fieldSelectedFromRecord
  10227. ;
  10228. anyFunction
  10229. : DATAROW_FUNCTION
  10230. | moduleScopeDot DATAROW_FUNCTION leaveScope
  10231. {
  10232. $1.release();
  10233. $$.setExpr($2.getExpr());
  10234. }
  10235. | DATASET_FUNCTION
  10236. | moduleScopeDot DATASET_FUNCTION leaveScope
  10237. {
  10238. $1.release();
  10239. $$.setExpr($2.getExpr());
  10240. }
  10241. | valueFunc