|
|
1.1 ! root 1: .th QUEL QUEL 2/23/79 ! 2: .ds QU \s-2QUEL\s0 ! 3: .sh NAME ! 4: quel \- \fBQUE\fPry \fBL\fPanguage for \*(II ! 5: .sh DESCRIPTION ! 6: The following is a description of the general syntax ! 7: of ! 8: .nh ! 9: \*(QU. ! 10: .hy ! 11: Individual ! 12: \*(QU ! 13: statements and commands ! 14: are treated separately in the document; ! 15: this section describes the syntactic classes from which the constituent ! 16: parts of ! 17: \*(QU ! 18: statements are drawn. ! 19: .s1 ! 20: 1. Comments ! 21: .s2 ! 22: A comment is an arbitrary sequence of characters ! 23: bounded on the left by ! 24: ``/\*(**'' ! 25: and on the right by ! 26: ``\*(**/'': ! 27: .s3 ! 28: /\*(** This is a comment \*(**/ ! 29: .s1 ! 30: 2. Names ! 31: .s2 ! 32: Names in ! 33: \*(QU ! 34: are sequences of no more than 12 alphanumeric ! 35: characters, starting with an alphabetic. Underscore (_) is considered ! 36: an alphabetic. ! 37: All upper-case alphabetics ! 38: appearing anywhere except in strings are automatically ! 39: and silently mapped into their ! 40: lower-case counterparts. ! 41: .s1 ! 42: 3. Keywords ! 43: .s2 ! 44: The following identifiers are reserved for use as keywords and ! 45: may not be used otherwise: ! 46: .s3 ! 47: .ft B ! 48: .if n .ta 5 25 45 ! 49: .if t .ta 0.5i 2.5i 4.5i ! 50: .de xx ! 51: \t\\$1\t\\$2\t\\$3 ! 52: .br ! 53: .. ! 54: .xx abs all and ! 55: .xx any append ascii ! 56: .xx at atan avg ! 57: .xx avgu by concat ! 58: .xx copy cos count ! 59: .xx countu create define ! 60: .xx delete delim destroy ! 61: .xx exp float4 float8 ! 62: .xx from gamma help ! 63: .xx in index int1 ! 64: .xx int2 int4 integrity ! 65: .xx into is log ! 66: .xx max min mod ! 67: .xx modify not of ! 68: .xx on onto or ! 69: .xx permit print range ! 70: .xx replace retrieve save ! 71: .xx sin sqrt sum ! 72: .xx sumu to unique ! 73: .xx until unuse use ! 74: .xx view where ! 75: .ft ! 76: .dt ! 77: .s1 ! 78: 4. Constants ! 79: .s2 ! 80: There are three types of constants, ! 81: corresponding to the three data types available in ! 82: \*(QU ! 83: for data storage. ! 84: .s1 ! 85: 4.1. String constants ! 86: .s2 ! 87: Strings in ! 88: \*(QU ! 89: are sequences of no more than 255 arbitrary ! 90: ASCII characters bounded by ! 91: double quotes ( " " ). Upper case alphabetics within strings ! 92: are accepted literally. ! 93: Also, in order to imbed quotes ! 94: within strings, it is necessary to prefix them with `\e' . ! 95: The same convention applies to `\e' itself. ! 96: .s3 ! 97: Only printing characters are allowed within strings. ! 98: Non-printing characters (i.e. control characters) ! 99: are converted to blanks. ! 100: .s1 ! 101: 4.2. Integer constants ! 102: .s2 ! 103: .br ! 104: Integer constants in ! 105: \*(QU ! 106: range from \*-2,147,483,647 ! 107: to +2,147,483,647. ! 108: Integer constants beyond that range will be converted to floating point. ! 109: If the integer is greater than 32,767 or less than \*-32,767 ! 110: then it will be left as a two byte integer. ! 111: Otherwise it is converted to a four byte integer. ! 112: .s1 ! 113: 4.3. Floating point constants ! 114: .s2 ! 115: Floating constants consist of an integer part, a decimal point, and ! 116: a fraction part or scientific notation ! 117: of the following format: ! 118: .s3 ! 119: {<dig>} [.<dig>] [e\*vE [+\*v\*-] {<dig>}] ! 120: .s3 ! 121: Where <dig> is a digit, [] represents zero or one, ! 122: {} represents zero or more, and | represents alternation. ! 123: An exponent with a missing mantissa has a mantissa ! 124: of 1 inserted. ! 125: There may be no extra characters embedded in the string. ! 126: Floating constants ! 127: are taken to be double-precision quantities with a range of ! 128: approximately ! 129: .if n -10**38 to +10**38 ! 130: .if t \*-10\x'-0.2v'\u\s-3\&38\s0\d to 10\u\x'-0.2v'\s-3\&38\s0\d ! 131: and a precision of 17 decimal digits. ! 132: .s1 ! 133: 5. Attributes ! 134: .s2 ! 135: An attribute is a construction of the form: ! 136: .s3 ! 137: variable.domain ! 138: .s3 ! 139: .it Variable ! 140: identifies a particular relation and can be thought of ! 141: as standing for the rows or tuples of that relation. ! 142: A variable is associated with a relation by means of a ! 143: .it range ! 144: statement. ! 145: .it Domain ! 146: is the name of one of the columns of the relation ! 147: over which the variable ranges. ! 148: Together they make up an attribute, which represents ! 149: values of the named domain. ! 150: .s2 ! 151: If the attribute is a string type, it can be qualified with the substring ! 152: notation. The substring notation is explained later. ! 153: .s1 ! 154: 6. Operators ! 155: .s1 ! 156: 6.1 Arithmetic operators ! 157: .s2 ! 158: Arithmetic operators take numeric type expressions as operands. ! 159: Unary operators group right to left; binary operators group ! 160: left to right. The operators (in order of descending ! 161: precedence) are: ! 162: .s3 ! 163: .nf ! 164: +,\*- (unary) plus, minus ! 165: \*(**\*(** exponentiation ! 166: \*(**,/ multiplication, division ! 167: +,\*- (binary) addition, subtraction ! 168: .dt ! 169: .fi ! 170: .i0 ! 171: .s3 ! 172: Parentheses may be used for arbitrary grouping. ! 173: Arithmetic overflow and divide by zero are ! 174: not checked on integer operations. ! 175: Floating point operations are checked for ! 176: overflow, underflow, and divide by zero only ! 177: if the appropriate machine hardware exists ! 178: and has been enabled. ! 179: .s1 ! 180: 6.2 Arithmetic string operators ! 181: .s2 ! 182: The operator \fI+\fR is a string concatenator, like the ! 183: \(*QU ! 184: function \fIconcat\fR; ! 185: however, its syntax is cleaner and it is not limited to two ! 186: arguments, ! 187: but like its arithmetic counterpart, ! 188: can be used without restriction. ! 189: Its counterpart, \fI-\fR, is the string equivalent of the difference ! 190: operator on sets, with the special property that only the first ! 191: instance of the right hand side is deleted from the string. ! 192: The binding properties of these two operators are exactly equivalent ! 193: to the arithmetic plus and minus, ! 194: which means that they can be used in conjunction with parentheses to ! 195: form complex expressions. ! 196: .s2 ! 197: These two operators are most useful when used with the substring notation. ! 198: .s1 ! 199: 7. Expressions (a_expr) ! 200: .s2 ! 201: An expression is one of the following: ! 202: .s3 ! 203: .nf ! 204: .if t .in +0.5i ! 205: .if n .in +5 ! 206: constant ! 207: attribute ! 208: functional expression ! 209: aggregate or aggregate function ! 210: a combination of numeric expressions and arithmetic operators ! 211: .i0 ! 212: .fi ! 213: .s3 ! 214: For the purposes of this document, ! 215: an arbitrary expression will be ! 216: refered to by the name ! 217: .it a_expr. ! 218: .s1 ! 219: 8. Formats ! 220: .s2 ! 221: Every ! 222: .it a_expr ! 223: has a format ! 224: denoted by ! 225: a letter (\c ! 226: .bd c, ! 227: .bd i, ! 228: or ! 229: .bd f, ! 230: for character, integer, or floating data ! 231: types respectively) and a number indicating the number of bytes ! 232: of storage occupied. ! 233: Formats currently supported are listed below. ! 234: The ranges of numeric types are indicated in parentheses. ! 235: .s3 ! 236: .lp +20 15 ! 237: c1 \- c255 character data of length 1\-255 characters ! 238: .lp +20 15 ! 239: i1 1-byte integer (\*-128 to +127) ! 240: .lp +20 15 ! 241: i2 2-byte integer (\*-32768 to +32767) ! 242: .lp +20 15 ! 243: i4 4-byte integer (\*-2,147,483,648 to +2,147,483,647) ! 244: .lp +20 15 ! 245: .if n f4 4-byte floating (\*-10**38 to +10**38, ! 246: .if t f4 4-byte floating (\*-10\x'-0.2v'\u\s-3\&38\s0\d to +10\x'-0.2v'\u\s-3\&38\s0\d, ! 247: 7 decimal digit precision) ! 248: .lp +20 15 ! 249: .if n f8 8-byte floating (\*-10**38 to +10**38, ! 250: .if t f8 8-byte floating (\*-10\u\x'-0.2v'\s-3\&38\s0\d to +10\u\x'-0.2v'\s-3\&38\s0\d, ! 251: 17 decimal digit precision) ! 252: .i0 ! 253: .s3 ! 254: One numeric format can be converted to ! 255: or substituted for any other numeric format. ! 256: .s1 ! 257: 9. Type Conversion. ! 258: .s2 ! 259: When operating on two numeric domains of ! 260: different types, ! 261: \*(II converts as necessary to make the ! 262: types identical. ! 263: .s3 ! 264: When operating on an integer and a floating ! 265: point number, ! 266: the integer is converted to a floating point ! 267: number before the operation. ! 268: When operating on two integers of different ! 269: sizes, the smaller is converted to ! 270: the size of the larger. ! 271: When operating on two floating point number ! 272: of different size, ! 273: the larger is converted to the smaller. ! 274: .s3 ! 275: The following table summarizes the possible combinations: ! 276: .s3 ! 277: .dt ! 278: .if n .in +4 ! 279: .if t .in +1i ! 280: .nf ! 281: i1 i2 i4 f4 f8 ! 282: .s3 ! 283: i1 \- i1 i2 i4 f4 f8 ! 284: i2 \- i2 i2 i4 f4 f8 ! 285: i4 \- i4 i4 i4 f4 f8 ! 286: f4 \- f4 f4 f4 f4 f4 ! 287: f8 \- f8 f8 f8 f4 f8 ! 288: .dt ! 289: .i0 ! 290: .fi ! 291: .s3 ! 292: \*(II provides five type conversion ! 293: operators specifically for ! 294: overriding the default actions. ! 295: The operators are: ! 296: .s3 ! 297: .nf ! 298: .in +4 ! 299: .if n .ta 18 ! 300: .if t .ta 1.4i ! 301: int1(a_expr) result type i1 ! 302: int2(a_expr) result type i2 ! 303: int4(a_expr) result type i4 ! 304: float4(a_expr) result type f4 ! 305: float8(a_expr) result type f8 ! 306: .dt ! 307: .fi ! 308: .i0 ! 309: .s3 ! 310: The type conversion operators convert their argument ! 311: a_expr to the requested type. ! 312: .it A_expr ! 313: can be anything including character. ! 314: If a character value cannot be converted, ! 315: an error occures and processing is halted. ! 316: This can happen only if the syntax of the ! 317: character value is incorrect. ! 318: .s3 ! 319: Overflow is not checked on conversion. ! 320: .s1 ! 321: 10. Target_list ! 322: .s2 ! 323: .br ! 324: A target list is a parenthesized, comma separated list of one ! 325: or more elements , each of which must be of one of the following ! 326: forms: ! 327: .s3 ! 328: a) ! 329: .it result_attname ! 330: .bd is ! 331: .it a_expr ! 332: .s3 ! 333: .it Result_attname ! 334: is the name of the attribute to be created (or an ! 335: already existing attribute name in the case of update statements.) ! 336: The equal sign (``='') may be used ! 337: interchangeably with ! 338: .bd is. ! 339: In the case where ! 340: .it a_expr ! 341: is anything other than ! 342: a single attribute, this form ! 343: must be used to assign a result ! 344: name to the expression. ! 345: .s3 ! 346: b) ! 347: .it attribute ! 348: .s3 ! 349: In the case of a ! 350: .it retrieve, ! 351: the resultant domain ! 352: will acquire the same name as that of the attribute being retrieved. ! 353: In the case of update statements ! 354: (\c ! 355: .it "append, replace\c" ! 356: ), ! 357: the relation being updated must have ! 358: a domain with exactly that name. ! 359: .s3 ! 360: Inside the target list the keyword ! 361: .bd all ! 362: can be used to represent all domains. ! 363: For example: ! 364: .if n .in +5 ! 365: .if t .in +0.5i ! 366: .s3 ! 367: range of e is employee ! 368: .br ! 369: retrieve (e.all) where e.salary > 10000 ! 370: .i0 ! 371: .s3 ! 372: will retrieve all domains of employee for ! 373: those tuples which satisfy the qualification. ! 374: .bd All ! 375: can be used in the target list of ! 376: a ! 377: .it retrieve ! 378: or an ! 379: .bd append. ! 380: The domains will be inserted in their ! 381: ``create'' order, that is, ! 382: the same order they were listed in the ! 383: .it create ! 384: statement. ! 385: .s1 ! 386: 11. Comparison operators ! 387: .s2 ! 388: Comparison operators take arbitrary expressions as operands. ! 389: .s3 ! 390: .dt ! 391: .nf ! 392: < (less than) ! 393: <= (less than or equal) ! 394: > (greater than) ! 395: >= (greater than or equal) ! 396: = (equal to) ! 397: != (not equal to) ! 398: .fi ! 399: .s3 ! 400: They are all of equal precedence. ! 401: When comparisons are made on ! 402: character attributes, all blanks are ignored. ! 403: .s1 ! 404: 12. Logical operators ! 405: .s2 ! 406: Logical operators take clauses as operands and ! 407: group left-to-right: ! 408: .s3 ! 409: .nf ! 410: not (logical not; negation) ! 411: and (logical and; conjunction) ! 412: or (logical or; disjunction) ! 413: .fi ! 414: .i0 ! 415: .dt ! 416: .s3 ! 417: .bd Not ! 418: has the highest precedence of the three. ! 419: .bd And ! 420: and ! 421: .bd or ! 422: have equal precedence. ! 423: Parentheses may be used for arbitrary grouping. ! 424: .s1 ! 425: 13. Qualification (qual) ! 426: .s2 ! 427: A ! 428: .it qualification ! 429: consists of any number of clauses connected ! 430: by logical operators. ! 431: A clause is a pair of expressions connected by a comparison operator: ! 432: .s3 ! 433: .dt ! 434: a_expr comparison_operator a_expr ! 435: .s3 ! 436: Parentheses may be used for arbitrary ! 437: grouping. ! 438: A qualification may thus be: ! 439: .s3 ! 440: .in +4 ! 441: .it clause ! 442: .br ! 443: .bd not ! 444: .it qual ! 445: .br ! 446: .it qual ! 447: .bd or ! 448: .it qual ! 449: .br ! 450: .it qual ! 451: .bd and ! 452: .it qual ! 453: .br ! 454: ( ! 455: .it qual ! 456: ) ! 457: .i0 ! 458: .s1 ! 459: 14. Functional expressions ! 460: .s2 ! 461: A ! 462: .it "functional expression" ! 463: consists of a function name followed ! 464: by a parenthesized (list of) operand(s). ! 465: Functional expressions can be nested to any level. ! 466: In the following list of functions supported (\c ! 467: .it n\c ! 468: ) ! 469: represents an arbitrary numeric type expression. ! 470: The format of the result is indicated on the right. ! 471: .s3 ! 472: .if n .ta 10 25 ! 473: .if n .in 24 ! 474: .if t .ta 1.0i 2.5i ! 475: .if t .in 2.5i ! 476: .de xx ! 477: .lp +20 15 ! 478: \fB\\$1(\fI\\$2\fB)\fR \-\t\c ! 479: .. ! 480: .xx abs n ! 481: same as ! 482: .it n ! 483: (absolute value) ! 484: .xx ascii n ! 485: character string (converts numeric to character) ! 486: .xx atan n ! 487: f8 (arctangent) ! 488: .xx concat a,b ! 489: character (character concatenation. See 16.2) ! 490: .xx cos n ! 491: f8 (cosine) ! 492: .xx exp n ! 493: f8 (exponential of ! 494: .it n\c ! 495: ) ! 496: .xx gamma n ! 497: f8 (log gamma) ! 498: .xx log n ! 499: f8 (natural logarithm) ! 500: .xx mod n,b ! 501: same as ! 502: .it b ! 503: (\c ! 504: .it n ! 505: modulo ! 506: .it "b. n" ! 507: and ! 508: .it b ! 509: must be i1, i2, or i4) ! 510: .xx sin n ! 511: f8 (sine) ! 512: .xx sqrt n ! 513: f8 (square root) ! 514: .dt ! 515: .i0 ! 516: .s1 ! 517: 15. Aggregate expressions ! 518: .s2 ! 519: Aggregate expressions provide a way to aggregate a computed expression ! 520: over a set of tuples. ! 521: .s1 ! 522: 15.1. Aggregation operators ! 523: .s2 ! 524: The definitions ! 525: of the aggregates are listed below. ! 526: .s3 ! 527: .de xx ! 528: .lp +20 15 ! 529: \fB\\$1\fP \-\t\c ! 530: .. ! 531: .xx count ! 532: (i4) count of occurrences ! 533: .xx countu ! 534: (i4) count of unique occurrences ! 535: .xx sum ! 536: summation ! 537: .xx sumu ! 538: summation of unique values ! 539: .xx avg ! 540: (f8) average (sum/count) ! 541: .xx avgu ! 542: (f8) unique average (sumu/countu) ! 543: .xx max ! 544: maximum ! 545: .xx min ! 546: minimum ! 547: .xx any ! 548: (i2) value is 1 if any tuples satisfy ! 549: the qualification, else it is 0 ! 550: .dt ! 551: .i0 ! 552: .s1 ! 553: 15.2. Simple aggregate ! 554: .s2 ! 555: .it "\taggregation_operator" ! 556: (\c ! 557: .it a_expr ! 558: [ ! 559: .bd where ! 560: .it qual ! 561: ] ) ! 562: .dt ! 563: .s3 ! 564: A simple aggregate evaluates to a single scalar value. ! 565: .it A_expr ! 566: is aggregated over the set of tuples satisfying ! 567: the qualification (or all tuples in the range of the expression if ! 568: no qualification is present). ! 569: Operators ! 570: .it sum ! 571: and ! 572: .it avg ! 573: require numeric type ! 574: .it a_expr; ! 575: .it "count, any, max" ! 576: and ! 577: .it min ! 578: permit a character type attribute as well as ! 579: numeric type ! 580: .it a_expr. ! 581: .s3 ! 582: .ul 1 ! 583: Simple aggregates are completely local. ! 584: That is, they are logically removed from the ! 585: query, processed separately, and replaced ! 586: by their scalar value. ! 587: .s1 ! 588: 15.3. ``\c ! 589: .bd any\c ! 590: \&'' ! 591: aggregate ! 592: .s2 ! 593: It is sometimes useful to know if any tuples satisfy a ! 594: particular qualification. ! 595: One way of doing this is by using the aggregate ! 596: .it count ! 597: and checking whether the return is zero or non-zero. ! 598: Using ! 599: .it any ! 600: instead of ! 601: .it count ! 602: is more efficient since ! 603: processing is stopped, if possible, the first time a tuple ! 604: satisfies a qualification. ! 605: .s3 ! 606: .it Any ! 607: returns 1 if the qualification is true ! 608: and 0 otherwise. ! 609: .s1 ! 610: 15.4. Aggregate functions ! 611: .s2 ! 612: .it "\taggregation_operator" ! 613: (\c ! 614: .it a_expr ! 615: .bd by ! 616: .it by_domain ! 617: .br ! 618: .it "\t\t{, by_domain}" ! 619: [ ! 620: .bd where ! 621: .it qual ! 622: ] ) ! 623: .s3 ! 624: Aggregate functions are extensions of simple aggregates. ! 625: The ! 626: .it by ! 627: operator groups (i.e. partitions) the set of qualifying tuples by ! 628: .it by_domain ! 629: values. ! 630: For more than one ! 631: .it by_domain, ! 632: the values which are grouped by are the concatenation ! 633: of individual ! 634: .it by_domain ! 635: values. ! 636: .it A_expr ! 637: is as in simple aggregates. ! 638: The aggregate function evaluates to a set of aggregate results, ! 639: one for each partition into which the set of qualifying ! 640: tuples has been grouped. ! 641: The aggregate value used during evaluation of the query is the ! 642: value associated with the partition into which ! 643: the tuple currently being processed would fall. ! 644: .s3 ! 645: Unlike simple aggregates, aggregate functions ! 646: are not completely local. ! 647: The ! 648: .it by_list, ! 649: which differentiates ! 650: aggregate functions from simple aggregates, ! 651: is global ! 652: to the query. ! 653: Domains in the ! 654: .it by_list ! 655: are automatically linked to the ! 656: other domains in the query which are ! 657: in the same relation. ! 658: .s3 ! 659: Example: ! 660: .ft B ! 661: .nf ! 662: /\*(** retrieve the average salary for the employees ! 663: working for each manager \*(**/ ! 664: range of e is employee ! 665: retrieve (e.manager, avesal=avg(e.salary by e.manager)) ! 666: .fi ! 667: .i0 ! 668: .ft ! 669: .s1 ! 670: 15.5 Aggregates on Unique Values. ! 671: .s2 ! 672: It is occasionally necessary to aggregate on ! 673: unique values of an expression. ! 674: The ! 675: .it avgu\c ! 676: , ! 677: .it sumu\c ! 678: , and ! 679: .it countu ! 680: aggregates ! 681: all remove duplicate values before ! 682: performing the aggregation. ! 683: For example: ! 684: .s3 ! 685: count(e.manager) ! 686: .s3 ! 687: would tell you how many occurrences of ! 688: .it "e.manager" ! 689: exist. ! 690: But ! 691: .s3 ! 692: countu(e.manager) ! 693: .s3 ! 694: would tell you how many unique values of ! 695: .it "e.manager" ! 696: exist. ! 697: .s1 ! 698: 16. Special character operators ! 699: .s2 ! 700: There are four special features which are particular ! 701: to character domains. ! 702: .s1 ! 703: 16.1 Pattern matching characters ! 704: .s2 ! 705: There are eleven characters which take ! 706: on special meaning when used in character constants ! 707: (strings): ! 708: .s3 ! 709: .de xx ! 710: .lp +10 6 ! 711: \\$1\t\c ! 712: .. ! 713: .xx \*(** ! 714: matches any string of zero or more characters. ! 715: .xx ? ! 716: matches any single character. ! 717: .xx [..] ! 718: matches any of characters in the brackets. ! 719: .xx ##1 ! 720: matches any string of zero or more characters. ! 721: .xx ##2 ! 722: matches any string of zero or more characters. ! 723: .xx ##3 ! 724: matches any string of zero or more characters. ! 725: .xx ##4 ! 726: matches any string of zero or more characters. ! 727: .xx ##5 ! 728: matches any string of zero or more characters. ! 729: .xx ##6 ! 730: matches any string of zero or more characters. ! 731: .xx ##7 ! 732: matches any string of zero or more characters. ! 733: .xx ##8 ! 734: matches any string of zero or more characters. ! 735: .xx ##9 ! 736: matches any string of zero or more characters. ! 737: .xx ##0 ! 738: matches all instances of strings between two occurances of ##0. ! 739: .i0 ! 740: .s3 ! 741: These characters can be used in any combination to ! 742: form a variety of tests. ! 743: For example: ! 744: .s3 ! 745: .lp +25 20 ! 746: where e.name = "##1Kalash##2Joe##4" \- matches any occurance of "Kalash", ! 747: followed by "Joe". ! 748: .lp +25 20 ! 749: where e.name = "##0Ingres##0" \- matches all occurances of "Ingres" within a line. ! 750: .lp +25 20 ! 751: where e.name = "\*(**" \- matches any name. ! 752: .lp +25 20 ! 753: where e.name = "E\*(**" \- matches any name starting with "E". ! 754: .lp +25 20 ! 755: where e.name = "\*(**ein" \- matches all names ending with "ein" ! 756: .lp +25 20 ! 757: where e.name = "\*(**[aeiou]\*(**" \- matches any name with at least one vowel. ! 758: .lp +25 20 ! 759: where e.name = "Allman?" \- matches any seven character name starting with "Allman". ! 760: .lp +25 20 ! 761: where e.name = "[A\-J]\*(**" \- matches any name starting with A,B,..,J. ! 762: .i0 ! 763: .s3 ! 764: The special meaning of the pattern matching characters ! 765: can be disabled by preceding them with a `\e'. ! 766: Thus ``\e\*(**'' refers to the character ``\*(**''. ! 767: When the special characters appear in the target ! 768: list they must be escaped. ! 769: For example: ! 770: .s3 ! 771: .dt ! 772: title = "\e\*(**\e\*(**\e\*(** ingres \e\*(**\e\*(**\e\*(**" ! 773: .s3 ! 774: is the correct way to assign the string ! 775: ``\*(**\*(**\*(** ingres \*(**\*(**\*(**'' to the domain ``title''. ! 776: .s1 ! 777: 16.1.1 Numbered Wildcards ! 778: .s2 ! 779: The numbered wildcards are unique in that they may also appear ! 780: in a target list, as well as in a qualification. ! 781: Each unique numbered wildcard used retains the same value ! 782: in both the target list and the qualification list. ! 783: Thus a query such as ! 784: .s1 ! 785: .lp +25 20 ! 786: replace t(text = "##1the##2") ! 787: .lp +30 20 ! 788: where t.text = "##1THE##2" ! 789: .i0 ! 790: .s1 ! 791: will replace an occurence of "THE" in t.text with "the". ! 792: .s1 ! 793: The special global wildcard ##0 when used in the query ! 794: .s1 ! 795: .lp +25 20 ! 796: replace t(text = "##0the##0") ! 797: .lp +30 20 ! 798: where t.text = "##0THE##0" ! 799: .i0 ! 800: .s1 ! 801: will replace all occurrences of "THE" with "the". ! 802: .s1 ! 803: 16.2 Concatenation ! 804: .s2 ! 805: There is a concatenation operator which can ! 806: form one character string from two. ! 807: Its syntax is ``concat(field1, field2)''. ! 808: The size of the new character string is the ! 809: sum of the sizes of the original two. ! 810: Trailing blanks are trimmed from the first ! 811: field, the second field is concatenated ! 812: and the remainder is blank padded. The result is never ! 813: trimmed to 0 length, however. ! 814: Concat can be arbitrarily nested inside other ! 815: concats. For example: ! 816: .s3 ! 817: .dt ! 818: name = concat(concat(x.lastname, ","), x.firstname) ! 819: .s3 ! 820: will concatenate ! 821: x.lastname with a comma and ! 822: then concatenate x.firstname to that. ! 823: .s1 ! 824: 16.3 Ascii (numeric to character translation) ! 825: .s2 ! 826: The ! 827: .it ascii ! 828: function can be used to convert a ! 829: numeric field to its character representation. ! 830: This can be useful when it is desired to compare ! 831: a numeric value with a character value. ! 832: For example: ! 833: .nf ! 834: .s3 ! 835: .dt ! 836: retrieve ( ... ) ! 837: where x.chardomain = ascii(x.numdomain) ! 838: .fi ! 839: .s3 ! 840: .it Ascii ! 841: can be applied to a character value. ! 842: The result is simply the character value unchanged. ! 843: The numeric conversion formats are determined by ! 844: the printing formats (see ingres(unix)). ! 845: .s1 ! 846: 16.4 Substring notation ! 847: .s2 ! 848: Any string attribute can be broken up into into a smaller substring ! 849: using the following substring operators. ! 850: .nf ! 851: .s3 ! 852: .dt ! 853: variable.domain(X,Y) ! 854: variable.domain(X,y% ! 855: variable.domain%X,Y) ! 856: variable.domain%X,Y% ! 857: .fi ! 858: Each of the above represents a certain substring of ! 859: .it domain, ! 860: denoted by the endpoints X and Y. Whether the endpoints are to be ! 861: included or not is determined by the parentheses (exclusion) and ! 862: percent signs (inclusion). ! 863: .s2 ! 864: \fIX\fR and \fIY\fR (optional) ! 865: consist of a required part with optional qualifiers. ! 866: The required part can be any of the following: ! 867: .nf ! 868: .s3 ! 869: .dt ! 870: a string ! 871: \*(lqw\*(rq \fR (a word) \fB ! 872: \*(lqc\*(rq \fR (a character) ! 873: A user defined delimiter (see delim(quel)) ! 874: .fi ! 875: .s2 ! 876: The optional qualifiers are a preceding digit, \fIi\fR, which specifies ! 877: to look for the \fI ith \fR occurence, and a trailing \fI$\fR, which ! 878: specifies to search backwards from the end of the string. ! 879: .s2 ! 880: The rules for searching are very simple. ! 881: Without the \fI$\fR, the value of \fIX\fR ! 882: chosen is the \fIith\fR occurrance (the default value of \fIi\fR is one) ! 883: from the left end of the string. ! 884: The search for \fIY\fR, if it is requested, starts after the end of \fIX\fR. ! 885: A dollar sign, however, always specifies that the search start from the end ! 886: of the string regardless of the value of \fIX\fR. ! 887: For illustrative purposes, assume a text field to contain the following: ! 888: .nf ! 889: .s3 ! 890: .dt ! 891: I saw the dog, the cat, and the duck take a walk. ! 892: .fi ! 893: Then the following constructs would have the attached values: ! 894: .nf ! 895: .s3 ! 896: .dt ! 897: r.text(3w,2"the"% dog, the cat, and the ! 898: r.text%2"the"$,$% the cat, and the duck take a walk. ! 899: .fi ! 900: .s2 ! 901: When combined with the \*(lqarithemtic\*(rq ! 902: string operators this facility can the quite powerful. ! 903: For example, to remove \*(lqthe dog\*(rq from the sentence requires ! 904: only the simple following query: ! 905: .nf ! 906: .s3 ! 907: .dt ! 908: replace r(text = r.text - r.text%"the","the")) ! 909: .fi ! 910: Or perhaps only the baby duck was taking a walk: ! 911: .nf ! 912: .s3 ! 913: .dt ! 914: replace r(text = r.text%"I","the"% + "baby" + r.text%"duck",$}) ! 915: .fi ! 916: .sh "SEE ALSO" ! 917: append(quel), ! 918: delete(quel), ! 919: delim(quel), ! 920: range(quel), ! 921: replace(quel), ! 922: retrieve(quel), ! 923: ingres(unix) ! 924: .sh BUGS ! 925: The maximum number of variables which can ! 926: appear in one query is 10. ! 927: .s3 ! 928: Numeric overflow, underflow, and divide by zero ! 929: are not detected. ! 930: .s3 ! 931: When converting between numeric types, overflow is ! 932: not checked.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.