MCPcopy Create free account
hub / github.com/dolthub/doltgresql / Extract

Method Extract

postgres/parser/pgdate/field_extract.go:108–276  ·  view source on GitHub ↗

Extract is the top-level function. It attempts to break the input string into a collection of date/time fields in order to populate a fieldExtract.

(s string)

Source from the content-addressed store, hash-verified

106// string into a collection of date/time fields in order to populate a
107// fieldExtract.
108func (fe *fieldExtract) Extract(s string) error {
109 // Break the string into alphanumeric chunks.
110 textChunks := make([]stringChunk, fieldMaximum)
111 count, _ := chunk(s, textChunks)
112
113 if count < 0 {
114 return inputErrorf("too many fields in input")
115 } else if count == 0 {
116 return inputErrorf("empty or blank input")
117 }
118
119 // Create a place to store extracted numeric info.
120 numbers := make([]numberChunk, 0, fieldMaximum)
121
122 appendNumber := func(prefix, number string) error {
123 v, err := strconv.Atoi(number)
124 if err != nil {
125 return err
126 }
127
128 // Allow exactly one non-whitespace separator.
129 s := ' '
130 for _, r := range prefix {
131 switch {
132 case s == ' ':
133 s = r
134 case unicode.IsSpace(r):
135 // Ignore whitespace characters.
136 default:
137 return inputErrorf(`detected multiple separators in "%s""`, prefix)
138 }
139 }
140
141 numbers = append(numbers, numberChunk{separator: s, v: v, magnitude: len(number)})
142 return nil
143 }
144
145 var leftoverText string
146
147 // First, we'll try to pluck out any keywords that exist in the input.
148 // If a chunk is not a keyword or other special-case pattern, it
149 // must be a numeric value, which we'll pluck out for a second
150 // pass. If we see certain sentinel values, we'll pick them out,
151 // but keep going to ensure that the user hasn't written something
152 // like "epoch infinity".
153 for idx, chunk := range textChunks[:count] {
154 match := strings.ToLower(chunk.Match)
155
156 switch match {
157 case keywordEpoch:
158 if err := fe.matchedSentinel(TimeEpoch, match); err != nil {
159 return err
160 }
161
162 case keywordInfinity:
163 if strings.HasSuffix(chunk.NotMatch, "-") {
164 if err := fe.matchedSentinel(TimeNegativeInfinity, match); err != nil {
165 return err

Callers 5

ParseDateFunction · 0.95
ParseTimeFunction · 0.95
ParseTimeWithoutTimezoneFunction · 0.95
ParseTimestampFunction · 0.95

Calls 14

matchedSentinelMethod · 0.95
nowMethod · 0.95
WantsMethod · 0.95
interpretNumberMethod · 0.95
validateMethod · 0.95
chunkFunction · 0.85
inputErrorfFunction · 0.85
fieldSetterUTCFunction · 0.85
fieldSetterJulianDateFunction · 0.85
IsSpaceMethod · 0.80
LoadLocationMethod · 0.80
AddAllMethod · 0.80

Tested by

no test coverage detected